问题
我有一个带有用于Hashtags的表的sql数据库,其中许多表的名称重复。
类似的语句
SELECT *
FROM HashTag
ORDER BY Name
返回类似
的内容Id | Name
1947 | test
1950 | sample
1962 | test
1963 | sample
1986 | test
2014 | example
我只想保留每个名称的ID最低的主题标签(“ test”为1947,“ sample”为1950),并使用此ID更新其他表,以替换较高的ID(例如:更新主题标签“ test” ;最低编号= 1947,较高编号= 1962,1986)。这些sql语句目前已手动更新,如下所示:
UPDATE HashTaggedActivity
SET [HashTag_id] = 1947
WHERE HashTag_id in (1962, 1986)
Update HashTaggedGroup
SET [HashTag_id] = 1947
WHERE HashTag_id in (1962, 1986)
DELETE ht
FROM HashTag ht
WHERE ht.Id in (1962, 1986)
在此之后,我必须对HashTag'sample'执行此操作,这是一个容易出错且乏味的过程。 HashTag'example'不是重复的,不应导致更新其他表。
对于表HashTag中重复名称的每次出现,是否有任何方法可以编写一条sql语句?
到目前为止我尝试过的事情
我认为我必须结合一条语句才能获得ID所定的重复计数
select ht.Id, ht.Name, htc.dupeCount
from HashTag ht
inner join (
SELECT ht.Name, COUNT(*) AS dupeCount
FROM HashTag ht
GROUP BY ht.Name
HAVING COUNT(*) > 1
) htc on ht.Name = htc.Name
ORDER BY Id
给出
Id | Name | dupeCount
1947 | test | 3
1950 | sample | 2
1962 | test | 3
1963 | sample | 2
1986 | test | 3
2014 | example | 1
根据dupeCount使用我的UPDATE和DELETE语句,但是我不确定如何执行;-)
提前致以最诚挚的问候,
迈克尔
答案 0 :(得分:0)
前两个update语句首先基于hashtag_id获得名称(最里面的选择),然后获取具有相同名称的hashtag中所有ID的最小值(下一步选择),然后相应地更新hashtag_id。 在这种情况下,它还将使用hashtag_id 1947和1950更新记录-但新值将与旧值相同。
update HashTaggedGroup
set hashtag_id =
(select min(id)
from hashtag h1
where (
select name
from hashtag h2
where h2.id=HashTaggedGroup.hashtag_id)=h1.name);
update HashTaggedActivity
set hashtag_id =
(select min(id)
from hashtag h1
where (
select name
from hashtag h2
where h2.id=HashTaggedActivity.hashtag_id)=h1.name);
以下删除操作适用于Mysql和SQLServer,可能需要对其他数据库进行调整(但是想法仍然相同)。如果确定来自hashtag的所有id都存在于HashTaggedActivity中,则可以简化查询。
delete h1 from hashtag as h1
inner join hashtag as h2 on
h1.name = h2.name and
h1.id > h2.id;
答案 1 :(得分:0)
我将使用窗口功能:
with ht as (
select ht.*, min(id) over (partition by name) as minid
from hashtag ht
)
update hta
set hashtag_id = ht.minid
from HashTaggedActivity hta join
ht
on hta.hashtag_id = ht.id
where ht.minid <> hta.hashtag_id;
然后以类似的方式进行删除:
with ht as (
select ht.*, min(id) over (partition by name) as minid
from hashtag ht
)
delete from ht
where ht.minid <> id;