[英]T-SQL and/or LINQ query with multiple criteria
我有以下示例多对多关系:
我正在构建一个UI,以允许用户选择要一起批处理的多个文档。 每个批次可以有很多文件; 除非该批次已作废,否则每个文档只能在一个批次中。
在此UI上,我需要显示可用的文档。 如果满足以下条件,则认为文档可用 :
样本数据:
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,是因为它没有作废并且没有分批处理
现在,假设我选择了文档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。 显然,这没有发生。
如何重写此查询以显示仅与无效批次相关联的文档,但如果它们也与非无效批次相关联,则排除它们?
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)
)
编辑答案以包括“不存在”。 现在,您已经阅读了完整的问题,这就是我想用来排除那些与文档相关联的非无效批次的记录的条件。
使用COUNT
和HAVING
:
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
子句中的第一个条件将搜索未批处理的文档,第二个条件将搜索已批处理但无效的文档。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.