SQL 中的条件行删除

Conditional Row Deleting in SQL

我有一个包含 4 列的 table。我需要删除一些基于代码和 ID 列的行。代码 1 启动我试图跟踪的进程,代码 2 终止它。当代码 2 出现在代码 1 之后并且没有附加代码 1 时,我想删除特定 ID 的所有行。例如,我当前的数据集如下所示:

Code  Deposit    Date        ID
1      0      3/2/2016    5
2      [=11=]        3/1/2016    5
1      0      2/8/2016    5
1      0      3/22/2016   4
2             2/8/2016    3
1      0      1/3/2016    3
2      [=11=]        6/15/2015   2
1      0      3/22/2016   2
1             8/15/2015   1
2      0      8/1/2015    1

在我 运行 我的脚本之后,我希望它看起来像这样:

Code  Deposit    Date        ID
1      0      3/2/2016    5
2      [=12=]        3/1/2016    5
1      0      2/8/2016    5
1      0      3/22/2016   4
1             8/15/2015   1
2      0      8/1/2015    1

在我的实际 table 中总共有大约 150,000 个 ID,但这是一般的想法。

我采用的方法是将每个 ID 的代码相加。如果恰好等于 3,则应将其删除。

;WITH keepID as (
Select
    ID
    ,SUM(code) as 'sumCode'
From #testInit
Group by ID
HAVING SUM(code) <> 3
)

Select *
From #testInit
Where ID IN (Select ID from keepID)

您的 post 显示保持 ID = 1,这似乎不符合条件?您确定要保留 ID = 1 吗?它只有 2 条记录,代码为 1,代码为 2,加起来为 3 ...因此,将其删除。

我只是展示了逻辑上的方法...如果您需要有关删除代码的帮助,请告诉我。

delete  from table 
where table.id in

(select id from B where A.id=B.id and B.date>A.date
from 
(select code,id,max(date),id where code=1 group by id) as A,
(select code ,id,max(date),id where code=2 group by id) as B) 

解释:select code,id,max(date),id where code=1 as A 将获取代码 1 的特定 ID 的最高日期的数据 select code ,id,max(date),id 其中 code=2 group by id) as B 将获取代码 2

的特定 ID 的最高日期的数据

select 来自 B 的 ID,其中 A.id=B.id 和 B.date>A.date 将 select 代码对应的所有 ID 2 日期高于代码 1 日期。

您可以使用如下逻辑获取 ID:

select t.id
from t
group by t.id
having max(case when code = 2 then date end) > min(case when code = 1 then date end) and -- code 2 after code 1
       max(case when code = 2 then date end) > max(case when code = 1 then date end) -- no code 1 after code2

然后很容易将其合并到查询中以获取其余详细信息:

select t.*
from t
where t.id not in (select t.id
                   from t
                   group by t.id
                   having max(case when code = 2 then date end) > min(case when code = 1 then date end) and -- code 2 after code 1
                          max(case when code = 2 then date end) > max(case when code = 1 then date end)
                  );