SQL-запрос для поиска записей, где количество> 1

177

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

ОБНОВЛЕНИЕ: Кроме того, должен быть фильтр, который только подсчитывает записи, почтовый индекс которых отличается.

Вот как выглядит таблица:

| user_id | account_no | почтовый индекс | дата |
| 1 | 123 | 55555 | 12 декабря 2009 года |
| 1 | 123 | 66666 | 12 декабря 2009 года |
| 1 | 123 | 55555 | 13-DEC-09 |
| 2 | 456 | 77777 | 14 декабря 2009 года |
| 2 | 456 | 77777 | 14 декабря 2009 года |
| 2 | 789 | 77777 | 14 декабря 2009 года |
| 2 | 789 | 77777 | 14 декабря 2009 года |

Результат должен выглядеть примерно так:

| user_id | считать |
| 1 | 2 |

Как бы вы выразили это в запросе SQL? Я думал сам присоединиться, но по какой-то причине мой счет неверен.

Бенджамин Мущко
источник

Ответы:

346

Используйте предложение HAVING и GROUP По полям, которые делают строку уникальной

Ниже найдете

все пользователи, имеющие более одного платежа в день с одним и тем же номером счета

SELECT 
 user_id ,
 COUNT(*) count
FROM 
 PAYMENT
GROUP BY
 account,
 user_id ,
 date
Having
COUNT(*) > 1

Обновление Если вы хотите включить только те из них, которые имеют отдельный ZIP, вы можете сначала получить отдельный набор, а затем выполнить HAVING / GROUP BY

 SELECT 
    user_id,
    account_no , 
    date,
        COUNT(*)
 FROM
    (SELECT DISTINCT
            user_id,
            account_no , 
            zip, 
            date
         FROM
            payment 

        ) 
        payment
 GROUP BY

    user_id,
    account_no , 

    date
HAVING COUNT(*) > 1
Конрад Фрикс
источник
1
Обратите внимание, что в его результатах 2есть подсчет: 4вы, вероятно, захотите отказаться от Account_noгруппировки.
JNK
Не ждите, я думаю, что оригинал был прав: «все пользователи, которые имеют более одного платежа в день с одним и тем же номером счета».
Конрад Фрикс
это говорит об этом, но его результаты показывают иначе. Возможно иметь обе версии с пометкой.
JNK
Спасибо за ваши ответы. Я думаю, что должен сделать это. Если бы я теперь хотел добавить другой фильтр, который проверяет, отличается ли платежный почтовый индекс (та же таблица, другой столбец) на ту же дату, как бы я изменил этот запрос?
Бенджамин Мущко
Я не могу разрешить пример вывода. Если мы удалим аккаунт, мы получим три строки. Если мы удалим и дату, и учетную запись, мы получим две строки 1,3 и 2,4. Так что я собираюсь доверять словам и выводам
Конрад Фрикс,
43

Попробуйте этот запрос:

SELECT column_name
  FROM table_name
 GROUP BY column_name
HAVING COUNT(column_name) = 1;
user4019456
источник
4
аккуратно, но это не отвечает на вопрос
Ламбарт
4

Я бы не рекомендовал это HAVINGключевое слово для новичков, оно в основном для устаревших целей .

Мне не ясно, что является ключом к этой таблице ( интересно, она полностью нормализована ?), Поэтому мне трудно следовать вашей спецификации:

Я хотел бы найти все записи для всех пользователей, которые имеют более одного платежа в день с тем же номером счета ... Кроме того, должен быть фильтр, который учитывает только те записи, почтовый индекс которых отличается.

Итак, я взял буквальное толкование.

Следующее более многословно, но может быть легче понять и, следовательно, поддерживать (я использовал CTE для таблицы, PAYMENT_TALLIESно это может быть VIEW:

WITH PAYMENT_TALLIES (user_id, zip, tally)
     AS
     (
      SELECT user_id, zip, COUNT(*) AS tally
        FROM PAYMENT
       GROUP 
          BY user_id, zip
     )
SELECT DISTINCT *
  FROM PAYMENT AS P
 WHERE EXISTS (
               SELECT * 
                 FROM PAYMENT_TALLIES AS PT
                WHERE P.user_id = PT.user_id
                      AND PT.tally > 1
              );
onedaywhen
источник
2
create table payment(
    user_id int(11),
    account int(11) not null,
    zip int(11) not null,
    dt date not null
);

insert into payment values
(1,123,55555,'2009-12-12'),
(1,123,66666,'2009-12-12'),
(1,123,77777,'2009-12-13'),
(2,456,77777,'2009-12-14'),
(2,456,77777,'2009-12-14'),
(2,789,77777,'2009-12-14'),
(2,789,77777,'2009-12-14');

select foo.user_id, foo.cnt from
(select user_id,count(account) as cnt, dt from payment group by account, dt) foo
where foo.cnt > 1;
iryndin
источник