【问题标题】:Removing all records where one condition is met删除满足一个条件的所有记录
【发布时间】:2021-12-26 19:49:54
【问题描述】:

我有一张如下表:

ID section Yes_no
EE_1 sec_21 Y
EE_1 sec_23 N
EE_1 sec_22 N
EE_2 sec_21 N

我正在寻找一种仅返回“Yes_no”列中没有“Y”的 ID 的方法。所需的输出如下:

ID section Yes_no
EE_2 sec_21 N

【问题讨论】:

  • @squillman 我想我对这个问题的解释很糟糕。当我使用 SELECT DISTINCT 时,我会返回两个 ID(EE_1 和 EE_2)。因为在某些情况下 EE_1 既是 Y/N 值
  • 因为EE_1既有Y又有N!如果该 ID 只有 Y 或同时包含 Y & N,则在输出中删除该记录。

标签: sql sql-server conditional-statements


【解决方案1】:

窗口函数通常是这类事情最快的

SELECT
  t.ID,
  t.section,
  t.Yes_no
FROM (
    SELECT *,
      CountY = COUNT(CASE WHEN t.Yes_no = 'Y' THEN 1 END) OVER (PARTITION BY t.ID)
    FROM YourTable t
) t
WHERE CountY = 0;

db<>fiddle

【讨论】:

  • 我只是问,因为我想了解更多...为什么 COUNT 比 NOT EXISTS 快?我猜 COUNT 恰好是最慢的,因为它必须计算所有记录(而 NOT EXISTS 会在找到匹配的第一条记录后立即结束)。谢谢
  • 不,这是一个窗口计数。每批具有相同ID 的行一起计算,表只扫描一次。而NOT EXISTS 是反连接,并且每行都会检查是否存在其他行,因此每行访问该表两次
  • 赞成你的回答!!!谢谢你的大师班;)
  • 此解决方案有效,感谢 Carlos & Charlieface 的帮助
【解决方案2】:

我想这就是你想要的:

create table MyTable(
  ID varchar(10),
  section varchar(50),
  Yes_no varchar(1)
)
insert into MyTable values 
('EE_1','sec_21','Y'),
('EE_1','sec_23','N'),
('EE_1','sec_22','N'),
('EE_2','sec_21','N')

select *
from MyTable t1
where t1.Yes_no = 'N' and not exists
(select * from MyTable t2 where t2.ID = t1.ID and t2.Yes_no = 'Y')

DBFiddler:https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=0b24198e227588df323c579facd37153

【讨论】:

    【解决方案3】:
    Select * from table_X where ID not in (Select ID from table_X where Yes_no ='Y')
    

    Running example

    【讨论】:

      【解决方案4】:

      您可以使用exists 关键字来执行此查询,因为exists 的性能优于in。

      select *
      from Table t
      where t.Yes_no = 'N' and not exists
      (select * from Table b where b.ID = b.ID and b.Yes_no = 'Y')
      

      【讨论】:

      • 虽然此代码可能会回答问题,但提供有关它如何和/或为什么解决问题的额外上下文将提高​​答案的长期价值。
      • 你可以使用“exists”关键字来执行这个查询,因为“exists”比“in”有更好的性能
      • 我的意思是你应该edit你的帖子来添加更多信息。不过没关系,我为你编辑了,把你在评论中提供的信息添加进去。
      猜你喜欢
      • 1970-01-01
      • 2016-12-04
      • 1970-01-01
      • 2017-09-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-03
      相关资源
      最近更新 更多