У меня есть база данных SQL Server организаций, и существует много дублирующихся строк. Я хочу выполнить избранный оператор, чтобы захватить все их и количество простофиль, но также и возвратить идентификаторы, которые связаны с каждой организацией.
Оператор как:
SELECT orgName, COUNT(*) AS dupes
FROM organizations
GROUP BY orgName
HAVING (COUNT(*) > 1)
Возвратит что-то как
orgName | dupes
ABC Corp | 7
Foo Federation | 5
Widget Company | 2
Но я также хотел бы захватить идентификаторы их. Там какой-либо путь состоит в том, чтобы сделать это? Возможно, как a
orgName | dupeCount | id
ABC Corp | 1 | 34
ABC Corp | 2 | 5
...
Widget Company | 1 | 10
Widget Company | 2 | 2
Так как причина - это существует также отдельная таблица пользователей, которые связываются с этими организациями, и я хотел бы объединить их (поэтому удаляют простофиль, таким образом, пользователи связываются с той же организацией вместо простофили orgs). Но я хотел бы часть вручную, таким образом, я ничего не завинчиваю, но мне все еще был бы нужен оператор, возвращая идентификаторы всей простофили orgs, таким образом, я могу пройти список пользователей.
select o.orgName, oc.dupeCount, o.id
from organizations o
inner join (
SELECT orgName, COUNT(*) AS dupeCount
FROM organizations
GROUP BY orgName
HAVING COUNT(*) > 1
) oc on o.orgName = oc.orgName
select orgname, count(*) as dupes, id
from organizations
where orgname in (
select orgname
from organizations
group by orgname
having (count(*) > 1)
)
group by orgname, id
Вы можете сделать это так:
SELECT
o.id, o.orgName, d.intCount
FROM (
SELECT orgName, COUNT(*) as intCount
FROM organizations
GROUP BY orgName
HAVING COUNT(*) > 1
) AS d
INNER JOIN organizations o ON o.orgName = d.orgName
Если вы хотите вернуть только записи, которые можно удалить (оставив один из каждого), вы можете использовать:
SELECT
id, orgName
FROM (
SELECT
orgName, id,
ROW_NUMBER() OVER (PARTITION BY orgName ORDER BY id) AS intRow
FROM organizations
) AS d
WHERE intRow != 1
Редактировать: SQL Server 2000 не имеет ROW_NUMBER () Функция. Вместо этого можно использовать:
SELECT
o.id, o.orgName, d.intCount
FROM (
SELECT orgName, COUNT(*) as intCount, MIN(id) AS minId
FROM organizations
GROUP BY orgName
HAVING COUNT(*) > 1
) AS d
INNER JOIN organizations o ON o.orgName = d.orgName
WHERE d.minId != o.id
Вы можете запустить следующие запросы и найти дубликаты с MAX (ID)
и удалите эти строки.
SELECT orgName, COUNT(*), Max(ID) AS dupes
FROM organizations
GROUP BY orgName
HAVING (COUNT(*) > 1)
Но вам придется запустить этот запрос несколько раз.