1、首先我們來先看一個簡單的例子:
有[Sales.Orders]訂單表和[Sales.Customers]顧客表,表的機構如下
業務要求:篩選 來自“按時打算”國家的用戶以及所下的訂單數
1 select 2 o.custid,COUNT(*) as '訂單數' 3 from [Sales.Orders] o inner join [Sales.Customers] c 4 on o.custid=c.custid 5 where c.country='按時打算' 6 group by o.custid;
這樣簡單的查詢,大家都能夠看明白,就不再解釋,就是使用了一個 內連接,和group by 進行分組,然后對分組后的數據進行 使用組函數Count進行求和
2、才是要講解的重點:三張表連接的 組函數的使用問題
這里要增加一張表:[Sales.OrderDetails]訂單詳細表:表結構:
業務要求:查詢出每個用戶 買了 多少件商品 下過多少訂單
1 select o.custid, 2 --SUM(qty):下面 用case是因為:組函數對 null 值不進行處理,所以含有求和之后返回null,而不是0 3 case 4 when SUM(qty) is null then '0' 5 else SUM(qty) 6 end 7 as '商品數量',-- count(*),(比原來的訂單數 多)--:相求訂單數量,這是錯的,因為三張表 關聯,這個時候,並不是級聯的 一對多的關系,況且,訂單表 處在 一對多的 關系的 中間 的位置 8 count( distinct o.orderid) as '訂單數'--將 重復的 訂單 刪除掉,這樣求出的數量就是 對的了 9 from [Sales.OrderDetails] od right join [Sales.Orders] o 10 on od.orderid=o.orderid inner join [Sales.Customers] c 11 on o.custid=c.custid 12 group by o.custid
說明:關於外連接和內連接的區別就不再說明,我在以前的文章里面已經進行說明了。現在說明為什么原來的 cunnt(*)是不對了,因為客戶表 1對多 訂單表,訂單表 1對多 訂單詳細表。所以就要注意了,連接之后就會根據 最多的,最底層的 訂單詳細表的數量為基准,產生 一張連接表,所以這個時候就會有很多的訂單的編號是重復的,所以直接求和就會有很多重復的數據也進行求和了,所以是錯的。應該對 消除重復的訂單編號 進行求和。