日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

全连接where 取最新日期_SQL学习笔记(4)——集合、连接与窗口函数

發布時間:2025/3/15 数据库 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 全连接where 取最新日期_SQL学习笔记(4)——集合、连接与窗口函数 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、集合?????

????????集合的運算常見如下五種:并(或)、交(和)、差、對稱差、補。

????????如果我們把表看成集合,表中的每一行記錄視為一個元素,那么集合運算對應到表查詢的關系如下表所示:

????????從數據處理的直接結果上看,集合運算改變了表查詢結果的行(行數不見得被改變),不涉及表間的字段關聯,即查詢結果沒有獲得原表字段之外的信息(注意:UNION的隱式類型轉化是例外)。

二、連接

????????承接有關集合最后的結論:從數據處理的直接結果上,連接改變了表查詢結果的字段(字段數可以選擇性地展示),依賴表間的字段關聯實現,即查詢結果獲得了原表字段以外的信息。

????????首要的一點是,由于SQL最先執行FROM子句,然后才是WHERE、GROUP BY,所以連接(FROM ... INNER/OUTER JOIN... ON..) 是最先完成的。實際上,把FROM后面的連接結果封裝成一個新的表即可,其他WHERE、GROUP、聚合等,都沒有變化。

??????連接類型可以不完備地分成以下三種,其特點總結如下表:

????????在實際的業務中,例如想要生成固定行數的單據時,就需要使用外連接,這是利用了外連接的“高寬容”特點。如果使用內連結的話,根據 SELECT 語句執行時商店庫存狀況的不同,結果的行數也會發生改變,生成的單據的版式也會受到影響,而使用外連結能夠得到固定行數的結果。

????????關于外連接的高寬容特點,以下例子可以更清楚地展現(例子來自教程4.2.2.2):

????????目的:使用外連結從?shopproduct?表和?product?表中找出那些在某個商店庫存少于50的商品及對應的商店.希望得到如下結果.

????????注意:高壓鍋和圓珠筆兩種商品在所有商店都無貨,也應該包括在內。

????????按照"結合WHERE子句使用內連結"的思路, 我們很自然會寫出如下代碼

SELECT P.product_id ,P.product_name ,P.sale_price ,SP.shop_id ,SP.shop_name ,SP.quantity FROM product AS P LEFT OUTER JOIN shopproduct AS SP ON SP.product_id = P.product_id WHERE quantity< 50

????????然而不幸的是, 得到的卻是如下的結果:

????????觀察發現, 返回結果缺少了在所有商店都無貨的高壓鍋和圓珠筆。因為WHERE 進行>或

????????然而在實際環境中,由于數據量大且數據質量并非像我們設想的那樣"干凈",我們并不能容易地意識到缺失值等問題數據的存在,因此,還是讓我們想一下如何改寫我們的查詢以使得它能夠適應更復雜的真實數據的情形吧。

????????聯系到我們已經掌握了的SQL查詢的執行順序(FROM->WHERE->SELECT),以及外連接的高寬容特點,我們發現, 問題可能出在篩選條件上, 因為在進行完外連接后才會執行WHERE子句,雖然外連接保留了quantity為NULL的數據,但后面執行的WHERE又把它們過濾掉了。

????????明白了這一點, 我們就可以試著把WHERE子句挪到外連結之前進行: 先寫個子查詢,用來從shopproduct表中篩選quantity<50的商品,,然后再把這個子查詢和主表連結起來.

我們把上述思路寫成SQL查詢語句:

SELECT P.product_id ,P.product_name ,P.sale_price ,SP.shop_id ,SP.shop_name ,SP.quantity FROM product AS P LEFT OUTER JOIN-- 先篩選quantity<50的商品 (SELECT * FROM shopproduct WHERE quantity < 50 ) AS SP ON SP.product_id = P.product_id

????????得到的結果如下:

????????總結:核心思路在于,把WHERE寫在子查詢內,讓能容納表外內容的OUTER JOIN(因為主表含高壓鍋和圓珠筆) 在無法容納NULL 的WHERE子句之后執行,以保證外連接的高寬容特點得以發揮。

三、窗口函數

以下對窗口函數的的引入,主要參考教程原文。

常規的SELECT語句都是對整張表進行查詢,而窗口函數可以讓我們有選擇的去某一部分數據進行匯總、計算和排序。

窗口函數的通用形式:

窗口函數(如:SUM、MAX、MIN(聚合)或RANK、DENSE_RANK ) OVER (PARTITION BY 列名 ORDER BY 排序用列名框架(如:ROWS n PRECEDING))


窗口函數最關鍵的是搞明白關鍵字PARTITON BY、ORDER BY和框架的作用。

PARTITON BY是用來分組,即選擇要看哪個窗口,類似于GROUP BY 子句的分組功能,但是PARTITION BY 子句并不具備GROUP BY 子句的匯總功能,并不會改變原始表中記錄的行數。

PS:如果不用PARTITION BY指定窗口范圍,則默認把整體看作一個窗口。

ORDER BY是用來排序,即決定窗口內,是按那種規則(字段)來排序的。

除了用PARTITION BY?指定窗口以外,還可以用框架指定窗口范圍,如:ROWS n PRECEDING?即把當前數據行與其前兩行(共三行)指定為窗口范圍。

# 關于ROLLUP子句的問題:

如果GROUP BY多個字段,即分組條件需符合 AND 判斷,交換product_tyoe 和 regist_date GROUP 結果不受影響(只是字段的顯示順序不一樣),但會影響 WITH ROLLUP 后的結果,放在前面的字段會被認為是需要ROLLUP(小計)的字段。

四、練習

練習題1:請說出針對本章中使用的 product(商品)表執行如下 SELECT 語句所能得到的結果。SELECT??product_id ,product_name ,sale_price ,MAX(sale_price) OVER (ORDER BY product_id) AS Current_max_price FROM product答:對改行數據及其以前的行的范圍內求最大值。練習題2:繼續使用product表,計算出按照登記日期(regist_date)升序進行排列的各日期的銷售單價(sale_price)的總額。排序是需要將登記日期為NULL 的“運動 T 恤”記錄排在第 1 位(也就是將其看作比其他日期都早)SELECT?product_name,?regist_date,??????SUM(sale_price)?OVER?(PARTITION?BY?regist_date?????????????????????????????ORDER?BY?regist_date)??AS?early_regist;????????????????????????????練習題3:① 窗口函數不指定PARTITION BY的效果是什么?答:如果不用PARTITION BY指定窗口范圍,則默認把整體看作一個窗口。② 為什么說窗口函數只能在SELECT子句中使用?實際上,在ORDER BY 子句使用系統并不會報錯。答:根據SQL執行順序,ORDER BY是在SELECT?執行后執行的,如果窗口函數寫在ORDER?BY子句后,則按照窗口函數結果排序,即沒有確切的排序結果,雖然不影響已有的SELECT結果(即不會報錯的原因),但ORDER BY 無意義。

總結

以上是生活随笔為你收集整理的全连接where 取最新日期_SQL学习笔记(4)——集合、连接与窗口函数的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。