SQL запит на пошук записів, де лічиться> 1


176

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

ОНОВЛЕННЯ: Крім того, повинен бути фільтр, а не тільки підраховувати записи, поштовий індекс яких відрізняється.

Ось так виглядає таблиця:

| user_id | рахунок_но | zip | дата |
| 1 | 123 | 55555 | 12-ДЕК-09 |
| 1 | 123 | 66666 | 12-ДЕК-09 |
| 1 | 123 | 55555 | 13-ДЕК-09 |
| 2 | 456 | 77777 | 14-ДЕК-09 |
| 2 | 456 | 77777 | 14-ДЕК-09 |
| 2 | 789 | 77777 | 14-ДЕК-09 |
| 2 | 789 | 77777 | 14-ДЕК-09 |

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

| user_id | рахувати |
| 1 | 2 |

Як би ви виразили це у запиті SQL? Я думав, що я приєднаюся, але я чомусь неправильно вважаю.

Відповіді:


345

Використовуйте пункт HAVING і GROUP По полях, які роблять рядок унікальним

Нижче знайдемо

всі користувачі, які мають більше одного платежу на день з тим самим номером рахунку

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

Оновлення Якщо ви хочете включити лише ті, які мають чіткий ZIP, ви можете спочатку отримати окремий набір, а потім виконати HAVING / GROUP

 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;

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
              );

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;
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.