2016-02-17 23 views
1

我有以下樣品許多一對多關係:T-SQL和/或LINQ查詢與多個條件

enter image description here

我建立一個UI,以允許用戶選擇多個文件是配合在一起。每個批次可以有多個文檔;每個文檔只能處於一個批處理中,除非批處理已被廢棄。

在此用戶界面上,我需要顯示可用文檔。文檔被看作可用如果是:

  • 不爲空,沒有成批的(即在BatchDocument記錄到它關聯到一個批次)
  • 不爲空,分批但批處理無效

樣本數據:

CREATE TABLE tmpDocument (DocumentID INT, IsVoid BIT) 

INSERT INTO tmpDocument VALUES (1,1) 
INSERT INTO tmpDocument VALUES (2,0) 
INSERT INTO tmpDocument VALUES (3,0) 
INSERT INTO tmpDocument VALUES (4,0) 
INSERT INTO tmpDocument VALUES (5,0) 
INSERT INTO tmpDocument VALUES (6,0) 
INSERT INTO tmpDocument VALUES (7,0) 
INSERT INTO tmpDocument VALUES (8,0) 
INSERT INTO tmpDocument VALUES (9,0) 

CREATE TABLE tmpBatch (BatchID INT, IsVoid BIT) 

INSERT INTO tmpBatch VALUES (1,0) 
INSERT INTO tmpBatch VALUES (2,1) 
INSERT INTO tmpBatch VALUES (3,0) 

CREATE TABLE tmpBatchDocument (BatchDocumentID INT, BatchID INT, DocumentID INT) 

INSERT INTO tmpBatchDocument VALUES (1,1,2) 
INSERT INTO tmpBatchDocument VALUES (2,1,3) 
INSERT INTO tmpBatchDocument VALUES (3,2,4) 
INSERT INTO tmpBatchDocument VALUES (4,2,5) 
INSERT INTO tmpBatchDocument VALUES (5,3,6) 
INSERT INTO tmpBatchDocument VALUES (6,3,7) 
INSERT INTO tmpBatchDocument VALUES (7,3,8) 

文獻

DocumentID---IsVoid 
1------------1----- 
2------------0----- 
3------------0----- 
4------------0----- 
5------------0----- 
6------------0----- 
7------------0----- 
8------------0----- 
9------------0----- 

BatchID------IsVoid 
1------------0----- 
2------------1----- 
3------------0----- 

BatchDocument

BatchDocumentID-----BatchID------DocumentID 
1-------------------1------------2--------- 
2-------------------1------------3--------- 
3-------------------2------------4--------- 
4-------------------2------------5--------- 
5-------------------3------------6--------- 
6-------------------3------------7--------- 
7-------------------3------------8---------  

要找到可用文件,我想出了這個T-SQL查詢:

SELECT a.DocumentID 
FROM tmpDocument a 
LEFT JOIN tmpBatchDocument b ON a.DocumentID = b.DocumentID 
LEFT JOIN tmpBatch c ON b.BatchID = c.BatchID 
WHERE (
     b.DocumentID IS NULL 
     AND a.IsVoid = 0 
     ) 
    OR (c.IsVoid = 1) 

查詢正確返回:

DocumentID 
4 
5 
9 

文獻1中排除,因爲它是無效的;文件2,3,6,7和8不包括在內,因爲它們是批量生產的,且批次沒有作廢;文件4和文件5包含在內,因爲雖然它們是批處理的,但批處理已經失效;包括文件9是因爲它沒有失效並且沒有批處理

現在,假設我選擇了Documents 4和5並將它們添加到新的批處理中。

BatchID------IsVoid 
1------------0----- 
2------------1----- 
3------------0----- 
4------------0----- 

BatchDocumentID-----BatchID------DocumentID 
1-------------------1------------2--------- 
2-------------------1------------3--------- 
3-------------------2------------4--------- 
4-------------------2------------5--------- 
5-------------------3------------6--------- 
6-------------------3------------7--------- 
7-------------------3------------8--------- 
8-------------------4------------4--------- 
9-------------------4------------5--------- 

運行相同的查詢返回相同的結果:

DocumentID 
4 
5 
9 

由於文獻4和5,現在關聯到一個非空隙化批次,我期望他們會從結果和僅文件被排除9會顯示。顯然,這沒有發生。

如何重寫此查詢以顯示僅與無效批次關聯的文檔,但如果它們也與無效批次關聯,則將其排除?

+0

什麼問題? –

+1

@FelixPamittan哇!對於那個很抱歉。提交超時,我不得不刷新頁面。我沒有注意到,當我發佈時,我的問題已經結束。 – Sesame

回答

0

使用COUNTHAVING

SELECT d.DocumentID 
FROM tmpDocument d 
LEFT JOIN tmpBatchDocument bd 
    ON bd.DocumentID = d.DocumentID 
LEFT JOIN tmpBatch b 
    ON b.BatchID = bd.BatchID 
WHERE 
    d.IsVoid = 0 
GROUP BY d.DocumentID 
HAVING 
    COUNT(bd.BatchDocumentID) = 0 
    OR COUNT(CASE WHEN b.IsVoid = 0 THEN 1 END) = 0 

WHERE條款顯然將排除作廢的文件。 HAVING子句中的第一個條件搜索未分批處理的文檔,第二個條件將搜索批處理文檔但批處理無效的文檔。

Try it here.

0
SELECT a.DocumentID 
FROM tmpDocument a 
LEFT JOIN tmpBatchDocument b ON a.DocumentID = b.DocumentID 
LEFT JOIN tmpBatch c ON b.BatchID = c.BatchID 
WHERE (
     b.DocumentID IS NULL 
     AND a.IsVoid = 0 --WHY? 
     ) 
    OR (c.IsVoid = 1 
     AND NOT EXISTS (select * from c2 where c2.batchID = (select batchID from b2 where b2.DocumentID=a.documentID) AND c2.isVoid=0) 
) 

編輯答案包括NOT EXISTS。現在讀完您的完整問題,我認爲您需要這樣做才能排除那些與文檔關聯的非空批次的記錄。

+0

如果沒有這個標準,文件1就會顯示出來。 – Sesame

+0

瞭解它,它檢查文檔的isvoid屬性,而不是批處理。 – CustodianOfCode