国产激情自拍_国产9色视频_丁香花在线电影小说观看 _久久久久国产精品嫩草影院

首頁 > 數據庫 > SQL Server > 正文

SQL點滴9—使用with語句來寫一個稍微復雜sql語句,附加和子查詢的性能對比

2019-11-03 08:33:10
字體:
來源:轉載
供稿:網友
今天偶爾看到sql中也有with關鍵字,好歹也寫了幾年的sql語句,居然第一次接觸,無知啊。看了一位博主的文章,自己添加了一些內容,做了簡單的總結,這個語句還是第一次見到,學習了。我從簡單到復雜地寫,希望高手們不要見笑。下面的sql語句設計到三個表,表的內容我用txt文件復制進去,這里不妨使用上一個隨筆介紹的建立端到端的package的方法將這些表導入到數據庫中,具體的就不說了。

從這里下載文件employees.txt,customers.txt,orders.txt

參考文章:http://www.cnblogs.com/wwan/archive/2011/02/24/1964279.html

使用package導入數據:http://www.cnblogs.com/tylerdonet/archive/2011/04/17/2017471.html

簡單的聚合

從orders表中選擇各個年份共有共有多少客戶訂購了商品

  •  第一種寫法,我們可以寫成這樣
    1select YEAR(o.orderdate) orderyear,COUNT(distinct(custid)) numCusts
    2from Sales.Orders o
    3group by YEAR(o.orderdate)
    4go
    要注意的是如果把group by YEAR(o.orderdata)換成group by orderyear就會出錯,這里涉及到sql語句的執行順序問題,有時間再了解一下          
  • 第二種寫法,
    1select orderyear,COUNT(distinct(custid))numCusts
    2from (select YEAR(orderdate) as orderyear,custid from sales.orders) as D
    3group by orderyear
    4go
    在from語句中先得到orderyear,然后再select語句中就不會出現沒有這個字段的錯誤了
  • 第三種寫法,
    1select orderyear,COUNT(distinct(custid)) numCusts
    2from (select YEAR(orderdate),custid from sales.orders) as D(orderyear,custid)
    3group by orderyear
    4go
    在as D后面加上選擇出的字段,是不是更加的清楚明了呢!
  • 第四種寫法,with出場了
    1with c as(
    2select YEAR(orderdate) orderyear, custid from sales.orders)
    3select orderyear,COUNT(distinct(custid)) numCusts from c group by orderyear
    4go
    with可以使語句更加的經湊,下面是權威解釋。  
        
    指定臨時命名的結果集,這些結果集稱為公用表表達式 (CTE)。該表達式源自簡單查詢,并且在單條 SELECT、INSERT、UPDATE、MERGE 或 DELETE 語句的執行范圍內定義。該子句也可用在 CREATE VIEW 語句中,作為該語句的 SELECT 定義語句的一部分。公用表表達式可以包括對自身的引用。這種表達式稱為遞歸公用表達式。               

                                                ----MSDN

  • 第五種寫法,也可以借鑒第三種寫法,這樣使語句更加清楚明了,便于維護
    1 with c(orderyear,custid) as(
    2  select YEAR(orderdate),custid from sales.orders)
    3  select orderyear,COUNT(distinct(custid)) numCusts from c group by c.orderyear
    4  go
    上面5中寫法都得到相同的結果,如下圖1:圖1

添加計算

  • 現在要求要求計算出訂單表中每年比上一年增加的客戶數目,這個稍微復雜
    1 with yearcount as(
    2  select YEAR(orderdate) orderyear,COUNT(distinct(custid)) numCusts from sales.orders group by YEAR(orderdate))
    3  select cur.orderyear curyear,cur.numCusts curNumCusts,PRv.orderyear prvyear,prv.numCusts prvNumCusts,cur.numCusts-prv.numCusts growth
    4  from yearcount cur left join yearcount prv on cur.orderyear=prv.orderyear+1
    5 go
    這里兩次使用到with結果集。查詢得到的結果如下圖2

    圖2

復雜的計算

  • 查找客戶id,這些客戶和所有來自美國的雇員至少有一筆交易記錄,查詢語句如下
    1 with TheseEmployees as(
    2 select empid from hr.employees where country='USA'),
    3 CharacteristicFunctions as(
    4 select custid,
    5 case when custid in (select custid from sales.orders as o where o.empid=e.empid) then 1 else 0 end as charfun
    6 from sales.customers as c cross join TheseEmployees as e)
    7 select custid,min(charfun) from CharacteristicFunctions group by custid having min(charfun)=1
    8 go
    這里嵌套with語句,第with語句查找美國雇員的id,第二個語句使用這個結果和擁有客戶的客戶id和擁有關系標識做笛卡爾積運算。最后從這個笛卡爾積中通過標識找到最終的custid。
    結果如下圖3

    圖3

這里只有簡單地介紹,沒有深入,高手們不要見笑啊。



---------------------------------------------------------分界線----------------------------------------------------------

with語句和子查詢的性能比較

在博友SingleCat的提醒下,對with語句做一些性能測試,這里使用的測試工具是SQL Server Profile。我選擇了最后一個語句,因為這個語句比較復雜一點。開始的時候單獨執行一次發現他們的差別不大,就差幾個毫秒,后來想讓他們多執行幾次,連續執行10

次看看執行的結果。下面貼出測試用的語句。

1 /*with查詢*/
2 declare @withquery varchar(5000)
3 declare @execcount int=0
4 set @withquery='with TheseEmployees as(
5 select empid from hr.employees where country=N''USA''),
6 CharacteristicFunctions as(
7 select custid,
8 case when custid in (select custid from sales.orders as o where o.empid=e.empid) then 1 else 0 end as charfun
9 from sales.customers as c cross join TheseEmployees as e)
10 select custid from CharacteristicFunctions group by custid having min(charfun)=1 order by custid
11 '
12 while @execcount<10
13 begin
14 exec (@withquery);
15 set @execcount=@execcount+1
16 end
17
18 /*子查詢*/
19 declare @subquery varchar(5000)
20 declare @execcount int=0
21 set @subquery='select custid from Sales.Orders where empid in
22 (select empid from HR.Employees where country = N''USA'') group by custid
23 having count(distinct empid)=(select count(*) from HR.Employees where country = N''USA'');
24 '
25 while @execcount<10
26 begin
27 exec (@subquery);
28 set @execcount=@execcount+1
29 end

SQL Server Profile中截圖如下

從圖中可以看到子查詢語句的執行時間要少于with語句,我覺得主要是with查詢中有一個cross join做了笛卡爾積的關系,于是又實驗了上面的那個簡單一點的,下面是測試語句。

1 /*with語句*/
2 declare @withquery varchar(5000)
3 declare @execcount int=0
4 set @withquery='with c(orderyear,custid) as(
5 select YEAR(orderdate),custid from sales.orders)
6 select orderyear,COUNT(distinct(custid)) numCusts from c group by c.orderyear'
7 while @execcount<100
8 begin
9 exec (@withquery);
10 set @execcount=@execcount+1
11 end
12
13 /*子查詢*/
14 declare @subquery varchar(5000)
15 declare @execcount int=0
16 set @subquery='select orderyear,COUNT(distinct(custid)) numCusts
17 from (select YEAR(orderdate),custid from sales.orders) as D(orderyear,custid)
18 group by orderyear'
19 while @execcount<100
20 begin
21 exec (@subquery);
22 set @execcount=@execcount+1
23 end

 

這次做10次查詢還是沒有多大的差距,with語句用10個duration,子查詢用了11個,有時候還會翻過來。于是把執行次數改成100,這次還是子查詢使用的時間要少,截圖如下

最終結論,子查詢好比with語句效率高。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
国产激情自拍_国产9色视频_丁香花在线电影小说观看 _久久久久国产精品嫩草影院
在线一区二区三区精品| 亚洲欧美小说国产图片| 青青久在线视频免费观看| 国产精品国精产品一二| 国产精品久久久久白浆| 中文av资源在线| 国产高清视频在线播放| av激情在线| 国产乱人视频免费播放| 精品国内自产拍在线视频| 九九热在线播放| 国产成在线观看免费视频| 在线观看免费黄色| 九九热视频精品在线观看| 综合激情亚洲| 亚洲尤物在线视频| 成人无遮挡免费网站视频在线观看| 日本中文字幕视频| 永久免费网站在线| 91超碰国产在线| www.五月色.com| 99视频免费| 欧美性受xxxx免费视频| 91欧美在线视频| 国产麻豆综合视频在线观看| av在线1区2区| 999国产在线视频| 国产精品一区二三区| 在线看黄网站| 国产偷窥老熟盗摄视频| 久久精品视频免费看| 国产成+人+亚洲+欧美+综合| 中文字幕在线看精品乱码| 美女被人操视频在线观看| 99在线免费视频| 999国产在线视频| 国产在线观看a| 青青青青在线| 波多野结衣中文字幕久久| 日本在线观看| www在线视频观看| gogo在线观看| 欧美卡一卡二| 国产在线看片| 国产免费av高清在线| 丁香在线视频| 最近高清中文在线字幕在线观看| 国内精品不卡| 中文字幕乱在线伦视频乱在线伦视频 | 日韩不卡高清| av网站大全在线| 99精品老司机免费视频| 亚洲图区欧美| 麻豆视频国产| 国产一二三区在线视频| √8天堂资源地址中文在线| 国产aa视频| 在线播放国产区| www.91在线播放| 日本中文字幕视频| 97影院秋霞午夜在线观看| 亚洲欧美日韩成人网| 黄网址在线播放免费| 最新中文字幕av专区| 中文字幕亚洲精品视频| 69免费视频| 免费a级在线播放| 国产高清大尺度一区二区不卡| 亚洲精品一线| 国产特黄在线| 香蕉视频在线看| 国产无遮挡又黄又爽免费网站 | 香蕉视频在线观看www| 久久精品国产亚洲777| 国产69精品久久app免费版 | av中文天堂在线| 99热最新网址| 四虎一区二区三区| 国产精品777一区二区| 欧美艹逼视频| 在线影视一区| 国产欧美日本亚洲精品一4区| 在线中文字幕第一页| 91caoporn在线| www.综合网.com| 国产二区视频| 最新中文字幕在线| 久热久精久品这里在线观看| 中文天堂av| 国产爆初菊在线观看免费视频网站| 开心快乐六月丁香婷婷| 午夜在线观看91| 在线观看av的网站| 99久久免费精品国产免费| 国产网红在线| 午夜国产在线| 国产精选在线观看| 导航福利在线| 中文字幕在线播放网址| 国产女人在线视频| 最近中文字幕大全中文字幕免费| 免费三级毛片| 免费在线黄色av| 美女永久在线网站| 国产乱妇乱子| 国产寡妇树林野战在线播放| 2020国产在线视频| 在线视频中文字幕久| 2019中文字幕视频| 伊人222成人综合网| 中文字幕2019第三页| 依依成人在线| 日本视频一二三区中文字幕| 日韩国产成人| 尤物视频在线观看| 精品亚洲综合| 久久99精品久久久久久野外| 最好2018中文免费视频| 国产经典av| 亚洲精品在线视频免费| 免费国产视频| 国产小视频在线观看| 精品999视频| 久久久久久77777| 国产经典自拍视频在线观看| 精品久久亚洲一级α| 久久99亚洲网美利坚合众国 | xxxxx中文字幕| 最好2018中文免费视频| 精品国产一区二区三区不卡在线 | av免费在线播放| 蜜桃av网站| 国产乱子伦三级在线播放| 精品欧美日韩一区二区| 日本aⅴ写真网站免费| 国产一级二级在线| 欧美日韩在线视频免费观看| 国产网友自拍电影在线 | 国产一卡2卡3卡四卡网站| 中文字幕av网| 高清视频一区二区三区四区| 在线播放黄色网址| 国产午夜在线| 免费99热在线观看| 国产在线观看网站| 超碰在线人人| 午夜国产福利在线| 亚洲天堂电影在线观看| 国产精品一区二区三区视频网站 | 狠狠操狠狠色| 亚洲v片在线观看| 国产福利在线看| 四虎国产精品永久| 国产不卡精品一区二区三区| 国产网站在线免费观看| 五月婷婷在线观看| 日本中文字幕高清视频| 黄网址在线播放免费| www亚洲天堂| а√最新版地址在线天堂| a视频在线播放| 日本亚洲精品| 免费a在线看| 九色视频网站| 好男人社区在线视频| 二区三区中文字幕| 成年人在线观看| 九九在线观看免费视频| 成年人在线观看| 国产一区二区影视| 国产午夜电影| 国产不卡在线| 亚洲精品天堂在线| 开心激情五月婷婷| 天天操人人干| 97影院秋霞午夜在线观看| 亚洲国产成人综合| 狠狠色综合久久婷婷| 中文字幕毛片| 在线观看午夜av| 黄色av免费看| 91视频久色| 青娱乐在线视频观看| 成人欧美精品久久久久影院| 中文字幕视频在线免费| 精品卡1卡2卡三卡免费网站| 日本不卡影院| 国产videos| 久久综合第一页| 国产精品乱码一区二区三区视频| 中文av在线播放| 天天操天天射天天色| 影音先锋日韩| 国产精品视频一区二区免费不卡| jlzzjlzz欧美| 精品黄色免费中文电影在线播放| 高清色视频在线观看| 精品国产二区三区| 中文字幕在线影视资源| av在线网页|