SQL: как найти дубликаты на основе двух полей?
У меня есть строки в таблице базы данных Oracle, которая должна быть уникальной для комбинации двух полей, но уникальное ограничение не настроено в таблице, поэтому мне нужно найти все строки, которые нарушают ограничение, используя SQL. К сожалению, мои скудные навыки SQL не справляются с этой задачей.
моя таблица имеет три столбца, которые имеют отношение: entity_id, station_id и obs_year. Для каждой строки комбинация station_id и obs_year должна быть уникальной, и я хочу узнать, есть ли являются строками, которые нарушают это, смывая их с помощью SQL-запроса.
я попробовал следующий SQL (предложенный этот предыдущий вопрос), но это не работает для меня (я получаю неопределенно определенный столбец ORA-00918):
SELECT
entity_id, station_id, obs_year
FROM
mytable t1
INNER JOIN (
SELECT entity_id, station_id, obs_year FROM mytable
GROUP BY entity_id, station_id, obs_year HAVING COUNT(*) > 1) dupes
ON
t1.station_id = dupes.station_id AND
t1.obs_year = dupes.obs_year
может кто-нибудь подсказать, что я делаю неправильно и/или как решить эту проблему?
8 ответов
SELECT *
FROM (
SELECT t.*, ROW_NUMBER() OVER (PARTITION BY station_id, obs_year ORDER BY entity_id) AS rn
FROM mytable t
)
WHERE rn > 1
SELECT entity_id, station_id, obs_year
FROM mytable t1
WHERE EXISTS (SELECT 1 from mytable t2 Where
t1.station_id = t2.station_id
AND t1.obs_year = t2.obs_year
AND t1.RowId <> t2.RowId)
перепишите свой запрос
SELECT
t1.entity_id, t1.station_id, t1.obs_year
FROM
mytable t1
INNER JOIN (
SELECT entity_id, station_id, obs_year FROM mytable
GROUP BY entity_id, station_id, obs_year HAVING COUNT(*) > 1) dupes
ON
t1.station_id = dupes.station_id AND
t1.obs_year = dupes.obs_year
Я думаю, что неоднозначная ошибка столбца (ORA-00918) была потому, что вы были select
ing столбцы, имена которых появились как в таблице, так и в подзапросе, но вы не указали, хотите ли вы этого от dupes
или mytable
(псевдоним t1
).
не могли бы вы создать новую таблицу, включающую уникальное ограничение, а затем скопировать по строкам данных, игнорируя сбои?
вам нужно указать таблицу для столбцов в главном select. Кроме того, предполагая, что entity_id является уникальным ключом для mytable и не имеет отношения к поиску дубликатов, вы не должны группировать его в подзапросе dupes.
попробуй:
SELECT t1.entity_id, t1.station_id, t1.obs_year
FROM mytable t1
INNER JOIN (
SELECT station_id, obs_year FROM mytable
GROUP BY station_id, obs_year HAVING COUNT(*) > 1) dupes
ON
t1.station_id = dupes.station_id AND
t1.obs_year = dupes.obs_year
SELECT *
FROM (
SELECT t.*, ROW_NUMBER() OVER (PARTITION BY station_id, obs_year ORDER BY entity_id) AS rn
FROM mytable t
)
WHERE rn > 1
по Quassnoi является наиболее эффективным для больших таблиц. У меня был такой анализ стоимости:
SELECT a.dist_code, a.book_date, a.book_no
FROM trn_refil_book a
WHERE EXISTS (SELECT 1 from trn_refil_book b Where
a.dist_code = b.dist_code and a.book_date = b.book_date and a.book_no = b.book_no
AND a.RowId <> b.RowId)
;
дал стоимость 1322341
SELECT a.dist_code, a.book_date, a.book_no
FROM trn_refil_book a
INNER JOIN (
SELECT b.dist_code, b.book_date, b.book_no FROM trn_refil_book b
GROUP BY b.dist_code, b.book_date, b.book_no HAVING COUNT(*) > 1) c
ON
a.dist_code = c.dist_code and a.book_date = c.book_date and a.book_no = c.book_no
;
дал стоимость 1271699
пока
SELECT dist_code, book_date, book_no
FROM (
SELECT t.dist_code, t.book_date, t.book_no, ROW_NUMBER() OVER (PARTITION BY t.book_date, t.book_no
ORDER BY t.dist_code) AS rn
FROM trn_refil_book t
) p
WHERE p.rn > 1
;
дал стоимостью 1021984
таблица не проиндексирована....
SELECT entity_id, station_id, obs_year
FROM mytable
GROUP BY entity_id, station_id, obs_year
HAVING COUNT(*) > 1
укажите поля для поиска дубликатов как в SELECT, так и в GROUP BY.
он работает с помощью GROUP BY
чтобы найти любые строки, которые соответствуют любым другим строкам на основе указанных столбцов.
The HAVING COUNT(*) > 1
говорит, что мы заинтересованы только в том, чтобы видеть любые строки, которые происходят более 1 раза (и поэтому являются дубликатами)