SQL-запрос для поиска записей, где количество> 1 - PullRequest
150 голосов
/ 22 августа 2011

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

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

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

| user_id | account_no | zip   |      date |
|       1 |        123 | 55555 | 12-DEC-09 | 
|       1 |        123 | 66666 | 12-DEC-09 |
|       1 |        123 | 55555 | 13-DEC-09 |
|       2 |        456 | 77777 | 14-DEC-09 |
|       2 |        456 | 77777 | 14-DEC-09 |
|       2 |        789 | 77777 | 14-DEC-09 |
|       2 |        789 | 77777 | 14-DEC-09 |

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

| user_id | count |
|       1 |     2 |

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

Ответы [ 4 ]

295 голосов
/ 22 августа 2011

Используйте предложение 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
36 голосов
/ 08 сентября 2014

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

SELECT column_name
  FROM table_name
 GROUP BY column_name
HAVING COUNT(column_name) = 1;
2 голосов
/ 23 августа 2011
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;
2 голосов
/ 23 августа 2011

Я бы не рекомендовал ключевое слово 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
              );
...