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)
);
我有一个包含 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)
);