我尝试了 Google 的不同解决方案,但找不到任何解决方案。谁能帮我解决以下情况的 SQL 选择查询。
主数据 | 用法 | 创建日期 | 动作旗帜 |
---|---|---|---|
彼得 | 未使用 | 2020-03-04 | 删除 |
彼得 | 未使用 |
|
保持 |
彼得 | 未使用 | 2019-04-12 | 删除 |
如果主数据列有相同的名称,并且都带有Not Used标志,那么我们将在最新创建的主数据的Action标志中设置“Keep”,为最新创建的masterdata设置Delete标志之前创建的那个。
主数据 | 用法 | 创建日期 | 动作旗帜 |
---|---|---|---|
约翰 | 未使用 | 2015-05-04 | 删除 |
约翰 | 二手 |
|
保持 |
如果主数据有相同的名称,一个有未使用标志,另一个有“已使用”标志,那么我们将为“已使用”的数据设置“保留”标志,为未使用的数据设置删除标志使用,无论日期如何。
主数据 | 用法 | 创建日期 | 动作旗帜 |
---|---|---|---|
托尼 | 二手 | 2020-05-04 | 删除和替换 |
托尼 | 二手 |
|
保持 |
如果主数据同名,都有Used标志,那么我们将对最近创建的数据有“Keep”标志,对之前创建的数据有“Delete and Replace”操作。
主数据 | 用法 | 创建日期 | 动作旗帜 |
---|---|---|---|
雷切尔 | 未使用 | 2020-12-10 | 删除 |
雷切尔 | 二手 |
|
保持 |
雷切尔 | 二手 | 2019-09-05 | 删除和替换 |
如果masterdata列同名,则有2个used flag和1个not used。
注意:
示例数据
主数据 | 用法 | 创建日期 | 动作旗帜 |
---|---|---|---|
雷切尔 | 未使用 | 2020-12-10 | 删除 |
雷切尔 | 二手 |
|
保持 |
雷切尔 | 二手 | 2019-09-05 | 删除和替换 |
托尼 | 二手 | 2020-05-04 | 删除和替换 |
托尼 | 二手 |
|
保持 |
约翰 | 未使用 | 2015-05-04 | 删除 |
约翰 | 二手 |
|
保持 |
彼得 | 未使用 | 2020-03-04 | 删除 |
彼得 | 未使用 |
|
保持 |
彼得 | 未使用 | 2019-04-12 | 删除 |
我希望在 SQL Server 中实现这一点。
这4个场景 7622 都可以通过SQL窗口函数处理,下面的排序方式和case语句.
排序方式(按用户):
以下案例陈述:
这里是查询:
with sorted_data AS (
select
masterdata,
usage,
createddate,
row_number() over (partition by masterdata order by (case when usage = 'Used' then 1 else 0 end) desc, createddate desc) as row_num
from
table1
)
select
masterdata,
usage,
createddate,
case when row_num = 1 then 'Keep'
when row_num > 1 and usage = 'Used' then 'Delete and Replace'
else 'Delete'
end as actionflag
from
sorted_data
主数据 | 用法 | 创建日期 | 动作旗帜 |
---|---|---|---|
约翰 | 二手 | 2016-06-05 | 保持 |
约翰 | 未使用 | 2015-05-04 | 删除 |
彼得 | 未使用 | 2023-01-05 | 保持 |
彼得 | 未使用 | 2020-03-04 | 删除 |
彼得 | 未使用 | 2019-04-12 | 删除 |
雷切尔 | 二手 | 2022-09-25 | 保持 |
雷切尔 | 二手 | 2019-09-05 | 删除和替换 |
雷切尔 | 未使用 | 2020-12-10 | 删除 |
托尼 | 二手 | 2021-03-01 | 保持 |
托尼 | 二手 | 2020-05-04 | 删除和替换 |
您需要找到要保留的行。一种方法是按优先级和日期排序:
with data as (
select *,
row_number() over (partition by masterdata
order by case usage when 'Used' then 1 else 2 end,
createddate desc) as rn
from T
)
select masterdata, usage, createddate,
case when rn = 1 then 'Keep'
when usage = 'Used' then 'Delete and Replace'
when usage = 'Not Used' then 'Delete'
end as actionflag
from data;
类似的逻辑,只是查找最近的日期并完成相同的目标。它可能会更快:
with data as (
select *,
case when createddate = max(createddate) over (partition by masterdata)
then 1 end as keep
from T
)
select masterdata, usage, createddate,
case when keep = 1 then 'Keep'
when usage = 'Used' then 'Delete and Replace'
when usage = 'Not Used' then 'Delete'
end as actionflag;
在第二个查询中有一些潜在的联系是日期不是唯一的。同样,出于同样的原因,第一个可能不是确定性的。