Sql 如果两个计数匹配,则删除记录

Sql 如果两个计数匹配,则删除记录,sql,sql-server,Sql,Sql Server,我有下表的数据 +---------+--------+--------+ | Trans | Status | Step | +---------+--------+--------+ | ABCDE | Comple | 1 +---------+--------+--------+ | ABCDE | Error | 2 +---------+--------+--------+ | FGHIJ | Comple | 1 +---------+--------+---

我有下表的数据

+---------+--------+--------+
| Trans   | Status | Step   |
+---------+--------+--------+
| ABCDE   | Comple | 1
+---------+--------+--------+
| ABCDE   | Error  | 2
+---------+--------+--------+
| FGHIJ   | Comple | 1
+---------+--------+--------+
| FGHIJ   | Comple | 2
+---------+--------+--------+
| KLMNO   | Comple | 1
+---------+--------+--------+
| KLMNO   | Comple | 2
+---------+--------+--------+
我只想删除trans计数和status='compi'与trans计数相同的记录

我可能会做一个光标和循环,但这是我不想做的事情

按照计数的思路思考,但可能有几英里远

谢谢


我只想删除FGHIJ和KLMNO,因为我知道所有步骤都已完成

我想保留abcde,因为并非所有步骤都已完成

这是您想要的吗

--delete 
select *
from yourtable t
where not exists
(
    select 1
    from yourtable t2
    where t1.Trans=t2.Trans
    and status<>'Comple'
)
按原样使用它,首先确保这是您要删除的内容,然后注释掉选择并取消注释删除

DECLARE @Data AS TABLE (Trans Varchar(10)   , Status  Varchar(10) , Step INT   )
INSERT INTO @Data
SELECT 'ABCDE', 'Comple' , 1 UNION ALL
SELECT 'ABCDE', 'Error'  , 2 UNION ALL
SELECT 'FGHIJ', 'Comple' , 1 UNION ALL
SELECT 'FGHIJ', 'Comple' , 2 UNION ALL
SELECT 'KLMNO', 'Comple' , 1 UNION ALL
SELECT 'KLMNO', 'Comple' , 2

SELECT * FROM @Data

;WITH CTe
AS
(
SELECT * , ROW_NUMBER()OVER(PArtition by Trans   , [Status] ORDER BY  Trans) AS TwocountsMatch
FROM @Data
)
DELETE FROM CTe WHERE TwocountsMatch=2 AND [Status]='Comple'


SELECT * FROM @Data

演示结果:

如果我理解正确,您是否希望删除所有[Trans]行,如果所有这些行[status]都是“Comple”

它通过在Trans上进行筛选来删除行,其中Trans组中的行数等于此组中具有Comple状态的行数


我假设您的分组值是Trans?您是说要删除状态为“comple”的Trans中不存在行的Trans吗?@TabAlleman我认为恰恰相反。他们想删除那些所有状态值都是comple的状态,只保留那些至少只有其他值的状态。@SeanLange是的,这就是我的意思。更正了我的评论。@PrashantPimpale-我觉得很清楚。如果您需要其他格式,也许您应该将其格式化并显示出来,因为您的定义可能不同。我认为他们不想删除匹配计数为2的行,我想他们想删除所有状态复杂的所有trans…我只想删除FGHIJ和KLMNO,因为我知道所有步骤都已完成。我想保留abcde,因为并非所有步骤都已完成。我只想删除FGHIJ和KLMNO,因为我知道所有步骤都已完成。我想保持abcde,因为并非所有步骤都已完成。这对我来说绝对是最明智的方法。
DECLARE @Data AS TABLE (Trans Varchar(10)   , Status  Varchar(10) , Step INT   )

INSERT INTO @Data
SELECT 'ABCDE', 'Comple' , 1 UNION ALL
SELECT 'ABCDE', 'Error'  , 2 UNION ALL
SELECT 'FGHIJ', 'Comple' , 1 UNION ALL
SELECT 'FGHIJ', 'Comple' , 2 UNION ALL
SELECT 'KLMNO', 'Comple' , 1 UNION ALL
SELECT 'KLMNO', 'Comple' , 2

SELECT * FROM @Data;

WITH
  summarised
AS
(
  SELECT
    * ,
    COUNT(*) OVER (PARTITION BY [trans]          )   AS count_trans,
    COUNT(*) OVER (PARTITION BY [trans], [status])   AS count_trans_status
  FROM
    @Data
)
DELETE
  summarised
WHERE
  [status] = 'Comple'
  AND count_trans = count_trans_status
;

SELECT * FROM @Data
DELETE FROM tbl
WHERE  Trans IN ( SELECT trans
                  FROM   tbl
                  GROUP  BY Trans
                  HAVING COUNT(*) = SUM(CASE WHEN status = 'Comple' THEN 1 ELSE 0 END) )