如何使用 UPDATE 合并和删除 SQL 中的重复行?
How do I merge and delete duplicated rows in SQL using UPDATE?
例如,我有一个 table 的:
id | code | name | type | deviceType
---+------+------+------+-----------
1 | 23 | xyz | 0 | web
2 | 23 | xyz | 0 | mobile
3 | 24 | xyzc | 0 | web
4 | 25 | xyzc | 0 | web
我想要的结果是:
id | code | name | type | deviceType
---+------+------+------+-----------
1 | 23 | xyz | 0 | web&mobile
2 | 24 | xyzc | 0 | web
3 | 25 | xyzc | 0 | web
如何在 SQL 服务器中使用 UPDATE
和 DELETE
语句执行此操作?
非常感谢任何帮助!
我实际上可能建议只保留原始数据,而不是在此处创建视图:
CREATE VIEW yourView AS
SELECT ROW_NUMBER() OVER (ORDER BY MIN(id)) AS id,
code, name, type,
STRING_AGG(deviceType, '&') WITHIN GROUP (ORDER BY id) AS deviceType
FROM yourTable
GROUP BY code, name, type;
不实际进行更新的一个主要原因是每次有新数据进来时,您可能不得不运行一遍又一遍地进行更新。相反,仅保留原始数据并 运行偶尔调整视图可能会在此处表现更好。
请注意,我假设您使用的是 SQL Server 2017 或更高版本。如果不是,那么 STRING_AGG
将不得不更换为更丑陋的方法,但在这种情况下您应该考虑升级。
要执行您想要的操作,您需要两个单独的语句。
这会使用组中的所有设备类型更新每个组的“第一”行:
update t
set t.devicetype = t1.devicetype
from mytable t
inner join (
select min(id) as id, string_agg(devicetype, '&') within group(order by id) as devicetype
from mytable
group by code, name, type
having count(*) > 1
) t1 on t1.id = t.id
这将删除每组除第一行以外的所有内容:
with t as (
select row_number() over(partition by code, name, type order by id) rn
from mytable
)
delete from t where rn > 1
例如,我有一个 table 的:
id | code | name | type | deviceType
---+------+------+------+-----------
1 | 23 | xyz | 0 | web
2 | 23 | xyz | 0 | mobile
3 | 24 | xyzc | 0 | web
4 | 25 | xyzc | 0 | web
我想要的结果是:
id | code | name | type | deviceType
---+------+------+------+-----------
1 | 23 | xyz | 0 | web&mobile
2 | 24 | xyzc | 0 | web
3 | 25 | xyzc | 0 | web
如何在 SQL 服务器中使用 UPDATE
和 DELETE
语句执行此操作?
非常感谢任何帮助!
我实际上可能建议只保留原始数据,而不是在此处创建视图:
CREATE VIEW yourView AS
SELECT ROW_NUMBER() OVER (ORDER BY MIN(id)) AS id,
code, name, type,
STRING_AGG(deviceType, '&') WITHIN GROUP (ORDER BY id) AS deviceType
FROM yourTable
GROUP BY code, name, type;
不实际进行更新的一个主要原因是每次有新数据进来时,您可能不得不运行一遍又一遍地进行更新。相反,仅保留原始数据并 运行偶尔调整视图可能会在此处表现更好。
请注意,我假设您使用的是 SQL Server 2017 或更高版本。如果不是,那么 STRING_AGG
将不得不更换为更丑陋的方法,但在这种情况下您应该考虑升级。
要执行您想要的操作,您需要两个单独的语句。
这会使用组中的所有设备类型更新每个组的“第一”行:
update t
set t.devicetype = t1.devicetype
from mytable t
inner join (
select min(id) as id, string_agg(devicetype, '&') within group(order by id) as devicetype
from mytable
group by code, name, type
having count(*) > 1
) t1 on t1.id = t.id
这将删除每组除第一行以外的所有内容:
with t as (
select row_number() over(partition by code, name, type order by id) rn
from mytable
)
delete from t where rn > 1