Найти строки с повторяющимися значениями в столбце

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

 author_id | author_name
 ----------+----------------
 9         | ernest jordan
 14        | k moribe
 15        | ernest jordan
 25        | william h nailon 
 79        | howard jason
 36        | k moribe

Теперь мне нужен результат как:

 author_id | author_name                                                  
 ----------+----------------
 9         | ernest jordan
 15        | ernest jordan     
 14        | k moribe 
 36        | k moribe

То есть мне нужен author_id для имен, которые повторяются. Я пробовал это утверждение:

select author_id,count(author_name)
from author_data
group by author_name
having count(author_name)>1

Но это не работает. Как я могу это получить?


person user3171906    schedule 28.03.2014    source источник


Ответы (3)


Я предлагаю оконную функцию в подзапросе:

SELECT author_id, author_name  -- omit the name here if you just need ids
FROM (
   SELECT author_id, author_name
        , count(*) OVER (PARTITION BY author_name) AS ct
   FROM   author_data
   ) sub
WHERE  ct > 1;

Вы узнаете основную агрегатную функцию count(). Ее можно превратить в оконную функцию, добавив предложение OVER - как и любую другую агрегатную функцию.

Таким образом подсчитываются строки на раздел. Вуаля.

Это необходимо сделать в подзапросе, потому что на результат нельзя ссылаться в предложении WHERE в том же SELECT (происходит после WHERE). Видеть:

В более старых версиях без оконных функций (v.8.3 или старше) - или в целом - эта альтернатива работает довольно быстро:

SELECT author_id, author_name  -- omit name, if you just need ids
FROM   author_data a
WHERE  EXISTS (
   SELECT FROM author_data a2
   WHERE  a2.author_name = a.author_name
   AND    a2.author_id <> a.author_id
   );

Если вас беспокоит производительность, добавьте указатель на author_name.

person Erwin Brandstetter    schedule 28.03.2014

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

попробуй это..

SELECT author_id, author_name
FROM author_data
WHERE author_id in (select author_id
        from author_data
        group by author_name
        having count(author_name)>1)
person SoulTrain    schedule 28.03.2014

Вы можете присоединить таблицу к самой себе, что возможно с помощью любого из следующих запросов:

SELECT a1.author_id, a1.author_name
FROM authors a1
CROSS JOIN authors a2
  ON a1.author_id <> a2.author_id
  AND a1.author_name = a2.author_name;

-- 9 |ernest jordan
-- 15|ernest jordan
-- 14|k moribe
-- 36|k moribe

--OR

SELECT a1.author_id, a1.author_name
FROM authors a1
INNER JOIN authors a2
  WHERE a1.author_id <> a2.author_id
  AND a1.author_name = a2.author_name;

-- 9 |ernest jordan
-- 15|ernest jordan
-- 14|k moribe
-- 36|k moribe
person coisnepe    schedule 21.12.2017