просмотреть все данные для повторяющихся строк в оракуле - PullRequest
8 голосов
/ 04 января 2012

У меня есть таблица с 6 столбцами:

  • id
  • name
  • type_id
  • code
  • lat
  • long

Требуются первые три.ID - это закрытый ключ, автоматически вставляемый с последовательностью.

У меня есть несколько строк, которые являются дубликатами, как определено ОБА, name и type_id равны, но я хотел бы просмотретьвсе данные для обманщиков.Я могу найти парней достаточно просто:

SELECT   name 
       , type_id
FROM   table1
GROUP BY name 
         , type_id
HAVING COUNT(*) > 1

, но на самом деле просмотр всей информации меня смущает.Я знаю, что это должно быть просто, но я бью стену здесь.

Ответы [ 5 ]

15 голосов
/ 04 января 2012

Вы всегда можете использовать запрос GROUP BY / HAVING в предложении IN.Это работает и является относительно простым, но это может быть не особенно эффективно, если количество повторяющихся строк относительно велико.

SELECT *
  FROM table1
 WHERE (name, type_id) IN (SELECT name, type_id
                             FROM table1
                            GROUP BY name, type_id
                           HAVING COUNT(*) > 1)

В целом было бы более эффективно использовать аналитические функции, чтобы избежать попадания в таблицувторой раз.

SELECT *
  FROM (SELECT id, 
               name,
               type_id,
               code,
               lat,
               long,
               count(*) over (partition by name, type_id) cnt
          FROM table1)
 WHERE cnt > 1

В зависимости от того, что вы планируете делать с данными, и сколько может быть дубликатов определенной строки, вы также можете присоединиться к table1 к себе, чтобы получить данные в одномстрока

SELECT a.name,
       a.type_id,
       a.id,
       b.id,
       a.code,
       b.code,
       a.lat,
       b.lat,
       a.long,
       b.long
  FROM table1 a
       JOIN table1 b ON (a.name = b.name AND
                         a.type_id = b.type_id AND
                         a.rowid > b.rowid)
1 голос
/ 04 января 2012

Вы можете самостоятельно объединиться на столе, чтобы найти все пары дубликатов:

SELECT 
  a.name    name
, a.type_id type_id_a
, a.code    code_a
, a.lat     lat_a
, a.long    long_a
, b.code    code_b
, b.lat     lat_b
, b.long    long_b
FROM table1 a
JOIN table1 b
ON  a.name    = b.name
AND a.type_id = b.type_id
AND a.ROWID > b.ROWID

Чтобы убедиться, что строка не соответствует самой себе и каждая пара выводится только один раз, я добавил a.ROWID > b.ROWID, который работает для Oracle. Если вы используете другую базу данных, вам потребуется другой способ их разделения.

1 голос
/ 04 января 2012
SELECT * 
FROM   table1 t1 
WHERE  (t1.name,t1.type_id) in ( SELECT DISTINCT name
                                               , type_id
                                 FROM     table1
                                 GROUP BY name, type_id
                                 HAVING COUNT(*) > 1 )

Сделал бы это.

НТН

0 голосов
/ 02 марта 2017

Просто сделайте NULLS 0 ...

... использовать функцию NVL.

0 голосов
/ 21 мая 2014

Это все еще не находит двойные значения, если одно из сравниваемых полей имеет значение NULL.Чтобы получить их, я использую nvl для связи значений NULL в сравниваемых полях со значением, которое, как я знаю, не может быть в этой таблице / поле.

...