2016-06-21 48 views
1

我在SQL Server,客戶,項目和事務中有3個表。來自表Transactions的C_id和I.id是來自Customers和Items表的外鍵。我想要一個特定的日期範圍來查看所有的客戶,所有的項目與他們的數量,要麼有或沒有交易。當該項目還沒有交易量爲0。SQL select客戶,來自事務處理的項目有和沒有事務

客戶(C)

id | Name 
1  | C1 
2  | C2 
3  | C3 

項目(I)

id | Name 
1 | I1 
2 | I2 
3 | I3 
4 | I4 

交易

id | C_id | I_id | qty | date 
1 | C1 | I1  | 10 | 2/2/2016 
2 | C2 | I3  | 5 | 3/2/2016 
3 | C1 | I2  | 3 | 3/2/2016 
4 | C2 | I1  | 8 | 4/2/2016 
5 | C1 | I1  | 2 | 5/2/2016 
6 | C1 | I2  | 4 | 5/2/2016 
7 | C2 | I1  | 2 | 6/2/2016 
8 | C1 | I1  | 100 | 1/3/2016 
9 | C2 | I2  | 200 | 2/3/2016 

我要爲數據範圍2016年2月2日和2016年10月2日之間的結果是:

C | I | qty 
C1 | I1 | 12 
C1 | I2 | 7 
C1 | I3 | 0 
C1 | I4 | 0 
C2 | I1 | 10 
C2 | I2 | 0 
C2 | I3 | 5 
C2 | I4 | 0 
C3 | I1 | 0 
C3 | I2 | 0 
C3 | I3 | 0 
C4 | I4 | 0 
+1

交叉連接,左連接,按 –

回答

1

試試這個,希望這有助於你,

select c.name,i.name,sum(isnull(t.qty,0)) 
from customers c 
cross join Items I 
left join transactions t on t.C_Id = C.Id and I.Id = t.I_Id and t.date between '2/2/2016' and '10/2/2016' 
group by c.name,i.name 
order by c.name,i.name 
+0

'如果項目還沒有交易量將0.' –

+0

我們只交易表的日期。所以當我們使用Date過濾這些值時,該項目必須是一個事務處理的項目。 – DineshDB

+0

此查詢僅返回具有事務的項目。我不想要這個。它沒有爲沒有交易的所有客戶返回物品。 – Andreas

3

如果你想有一個所有客戶的所有項目的完整列表,然後你想交叉加入這兩個表。然後,您可以使用您之後的日期範圍對交易表執行左連接。

讓我們來製作您的測試數據;

IF OBJECT_ID('tempdb..#Customers') IS NOT NULL DROP TABLE #Customers 
GO 
CREATE TABLE #Customers (id int, Name varchar(2)) 
INSERT INTO #Customers (id, Name) 
VALUES 
(1,'C1') 
,(2,'C2') 
,(3,'C3') 

IF OBJECT_ID('tempdb..#Items') IS NOT NULL DROP TABLE #Items 
GO 
CREATE TABLE #Items (id int, Name varchar(2)) 
INSERT INTO #Items (id, Name) 
VALUES 
(1,'I1') 
,(2,'I2') 
,(3,'I3') 
,(4,'I4') 

IF OBJECT_ID('tempdb..#Transactions') IS NOT NULL DROP TABLE #Transactions 
GO 
CREATE TABLE #Transactions (id int, C_id varchar(2), I_id varchar(2), qty int, date datetime) 
INSERT INTO #Transactions (id, C_id, I_id, qty, date) 
VALUES 
(1,'C1','I1',10,'2016-02-02') 
,(2,'C2','I3',5,'2016-02-03') 
,(3,'C1','I2',3,'2016-02-03') 
,(4,'C2','I1',8,'2016-02-04') 
,(5,'C1','I1',2,'2016-02-05') 
,(6,'C1','I2',4,'2016-02-05') 
,(7,'C2','I1',2,'2016-02-06') 
,(8,'C1','I1',100,'2016-03-01') 
,(9,'C2','I2',200,'2016-03-02') 

並且您需要查詢;

DECLARE @StartDate datetime; SET @StartDate = '2016-02-02' 
DECLARE @EndDate datetime; SET @EndDate = '2016-02-10' 

SELECT 
c.Name Cust_ID 
,i.Name Item_ID 
,SUM(ISNULL(t.qty,0)) Qty 
FROM #Customers c 
CROSS JOIN #Items i 
LEFT JOIN #Transactions t 
    ON c.Name = t.C_id 
    AND i.Name = t.I_id 
    AND t.date BETWEEN @StartDate AND @EndDate 
GROUP BY c.Name, i.Name 
ORDER BY c.Name, i.Name 

給出這些結果;

Cust_ID Item_ID Qty 
C1  I1  12 
C1  I2  7 
C1  I3  0 
C1  I4  0 
C2  I1  10 
C2  I2  0 
C2  I3  5 
C2  I4  0 
C3  I1  0 
C3  I2  0 
C3  I3  0 
C3  I4  0 
+0

加1爲精細解釋.. – DineshDB

+0

非常感謝。它工作正常。 – Andreas

+0

很有幫助。隨時upvote任何你認爲有用的答案,並標記爲接受的答案。謝謝 –