在另一个值上过滤具有非唯一 ID 的 SQL 行

Filter SQL rows with non unique IDs on another value

我有一个相当大的 SQL 请求,它生成以下语句(为清楚起见进行了简化):

但是,我需要过滤这个结果,只得到没有 CapacityId = 4 的 LabId。 在此示例中,预期结果仅为 LabId 7

这里是 fiddle 重现的情况:http://sqlfiddle.com/#!18/e581a/2

有了这个请求:

CREATE TABLE Lab (LabId int, CapacityId int)

INSERT INTO Lab (LabId, CapacityId)
VALUES (1, 1), (1, 2), (1, 3), (1, 4), (2, 1),(2, 2)

SELECT LabId 
FROM Lab 
WHERE CapacityId != 4
GROUP BY LabId

它仍然检索两个实验室,因为它们至少有一行 CapacityId != 4

我应该如何 WHERE/GROUP BY 只获得没有 CapacityId = 4 的实验室?

您可以使用 having:

SELECT LabId 
FROM Lab 
GROUP BY LabId
HAVING SUM(CASE WHEN CapacityId = 4 THEN 1 ELSE 0 END) = 0;

SUM() 将每个 LabId 具有 4 容量的行数相加。 = 0 指定有 none.

注意:这不是 returns LabId 中没有行的 table(技术上也满足此条件)。为此,请使用 NOT EXISTS。让我假设 table 的命名有点不同:

SELECT l.LabId 
FROM Labs l
WHERE NOT EXISTS (SELECT 1
                  FROM LabCapacity lc
                  WHERE lc.LabId = l.LabId AND
                        lc.CapacityId = 4
                 );

您可以在此处使用现有逻辑:

SELECT l1.LabId
FROM Lab l1
WHERE NOT EXISTS (SELECT 1 FROM Lab l2 WHERE l2.LabId = l1.LabId AND
                                             l2.CapacityId = 4);

您也可以使用聚合:

SELECT LabId 
FROM Lab 
GROUP BY LabId
HAVING COUNT(CASE WHEN CapacityId = 4 THEN 1 END) = 0;

使用解析函数

SELECT LabId 
FROM (select labId, CapacityId, 
        sum(case when CapacityId=4 then 1 else 0 end) over(partition by labId) cnt_capacyty4
       from Lab
     ) 
WHERE cnt_capacyty4 = 0
GROUP BY LabId