Client表:

[CID] [Name] [Age]
1 ABC 12
2 ACC 15
3 BBB 12

Status表:

[SID] [CID] [Status]
1 1 Active
2 1 Not Active
3 1 Unknown
4 2 Active
5 3 Active
6 3 Unknown

客户端表已连接到[CID]上的状态表.我想要未将任何状态设置为"非活动"的客户端的[CID].

以下是我的try :

SELECT 
    A.[CID], B.[Status] 
FROM
    [Client table] AS A
INNER JOIN 
    [Status table] B ON A.[CID] = B.[CID]
WHERE 
    B.[Status] = 'Not Active' 

在这种情况下,它应该显示CID为2&3的客户端,而不是显示CID为1的客户端.但是,在设置状态=非活动的情况下,我得到了所有的CID 1、2和3.通过上面的查询,我得到了所有三个CID.

如何改进我的查询以仅显示CID 2和3,以及我在这里做错了什么?

推荐答案

NOT EXISTS是实现这一目标的最有效方式.

遗憾的是,SQL Server要求子查询中至少有一列,因此您只能 Select SELECT 1SELECT NULL.无论您做什么都会被忽略,它只是在子查询中查找行的存在(或不存在).注意与内部WHERE中的外部查询的相关性.

SELECT
  c.CID
FROM Client c
WHERE NOT EXISTS (SELECT 1
    FROM Status s
    WHERE s.CID = c.CID   -- correlation
      AND s.Status = 'Not Active'
);

如果您实际上希望使用联接查看所有Status行,则窗口函数可能是最佳 Select .

在这里,我们使用一个窗口函数,它可以一次计算多个行,同时仍然返回所有行,而不是聚合.在这里,PARTITION BY的工作方式类似于GROUP BY,而CASE WHEN使其具有条件,因此它只计算符合条件的行数.

SELECT
  c.CID
FROM Client c
JOIN (
    SELECT s.*,
      countNotActive = COUNT(CASE WHEN s.Status = 'Not Active' THEN 1 END) OVER (PARTITION BY s.CID)
    FROM Status s
) s ON s.CID = c.CID
WHERE s.countNotActive = 0;

Sql相关问答推荐

帮助修复查询以识别SQL DW中数据中的递归关系

Snowflake SQL比较克隆x原始计数

如何在T—SQL中找到值更改之前的日期?

基于列对多行求和的查询

SQL SELECT MOST NEST TIMESTAMP BEAT ORDER

我怎样才能得到列值对应的最大值在另一个?

如何将我的联接数据放入每个用户每月多行的列中?

将日期时间转换为日期格式

在SQL中为两个日期之间的每个日期添加行

从每月生成的系列中生成每日汇率

列(值不为空)到其他有序列

达到特定值时,从0开始累加求和

Postgres如何在一个日历周中前进和回填值

如何从一张表中获取值在至少三行相同的记录

如何优化仅返回符合条件的三条记录的查询?

Oracle PL/SQL长期运行问题

如何将 CONCATENATED 值与临时表中的值匹配

我需要遍历权重值表并确定每个权重是否有效

CURRENT_ROW 窗口框架上的 SQL 滞后

使用一组值进行分组和计数