繁体   English   中英

具有多个条件的T-SQL和/或LINQ查询

[英]T-SQL and/or LINQ query with multiple criteria

我有以下示例多对多关系:

在此输入图像描述

我正在构建一个UI,以允许用户选择要一起批处理的多个文档。 每个批次可以有很多文件; 除非该批次已作废,否则每个文档只能在一个批次中。

在此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,是因为它没有作废并且没有分批处理

现在,假设我选择了文档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)
)

编辑答案以包括“不存在”。 现在,您已经阅读了完整的问题,这就是我想用来排除那些与文档相关联的非无效批次的记录的条件。

使用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子句中的第一个条件将搜索未批处理的文档,第二个条件将搜索已批处理但无效的文档。

在这里尝试。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM