Zapytanie SQL o znalezienie rekordów, w których liczba> 1

176

Mam tabelę o nazwie PAYMENT. W tej tabeli mam identyfikator użytkownika, numer konta, kod pocztowy i datę. Chciałbym znaleźć wszystkie rekordy dla wszystkich użytkowników, którzy mają więcej niż jedną płatność dziennie z tym samym numerem konta.

AKTUALIZACJA: Dodatkowo powinien istnieć filtr, który liczy tylko rekordy z innym kodem pocztowym.

Tak wygląda stół:

| identyfikator_użytkownika | account_no | zip | data |
| 1 | 123 | 55555 | 12 GRUDNIA 09 |
| 1 | 123 | 66666 | 12 GRUDNIA 09 |
| 1 | 123 | 55555 | 13 GRUDNIA 09 |
| 2 | 456 | 77777 | 14 GRUDNIA 09 |
| 2 | 456 | 77777 | 14 GRUDNIA 09 |
| 2 | 789 | 77777 | 14 GRUDNIA 09 |
| 2 | 789 | 77777 | 14 GRUDNIA 09 |

Wynik powinien wyglądać podobnie do tego:

| identyfikator_użytkownika | liczyć |
| 1 | 2 |

Jak byś wyraził to w zapytaniu SQL? Myślałem o samodzielnym dołączeniu, ale z jakiegoś powodu moje obliczenia są złe.

Benjamin Muschko
źródło

Odpowiedzi:

345

Użyj klauzuli HAVING i GROUP By pola, które sprawiają, że wiersz jest unikalny

Poniżej znajdziesz

wszyscy użytkownicy, którzy mają więcej niż jedną płatność dziennie na ten sam numer konta

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

Aktualizacja Jeśli chcesz uwzględnić tylko te, które mają odrębny ZIP, możesz najpierw uzyskać inny zestaw, a następnie wykonać 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
Conrad Frix
źródło
1
Zauważ, że w jego wynikach 2jest liczba 4- Account_noMyślę, że będziesz chciał odrzucić zgrupowanie.
JNK
Nie czekaj. Myślę, że oryginał miał rację „wszyscy użytkownicy, którzy mają więcej niż jedną płatność dziennie z tym samym numerem konta”.
Conrad Frix
tak mówi, ale jego wyniki pokazują inaczej. Może mieć obie wersje z dopiskiem.
JNK
Dziękuję za odpowiedzi. Myślę, że to powinno wystarczyć. Gdybym teraz chciał dodać kolejny filtr, który sprawdza, czy kod pocztowy rozliczenia (ta sama tabela, inna kolumna) jest inny dla tej samej daty, jak zmodyfikowałbym to zapytanie?
Benjamin Muschko
Nie mogę rozwiązać przykładowego wyjścia. Jeśli usuniemy konto, otrzymamy trzy wiersze. Jeśli porzucimy zarówno datę, jak i konto, otrzymamy dwa wiersze 1, 3 i 2, 4. Więc mam zamiar iść dalej i zaufać słowom nad wynikami
Conrad Frix
43

Spróbuj tego zapytania:

SELECT column_name
  FROM table_name
 GROUP BY column_name
HAVING COUNT(column_name) = 1;
user4019456
źródło
4
schludnie, ale to nie odpowiada na pytanie
Lambart
4

Nie polecałbym tego HAVINGsłowa kluczowego początkującym, jest zasadniczo do celów starszych .

Nie wiem, co jest kluczem do tej tabeli ( zastanawiam się, czy jest w pełni znormalizowana ?), W związku z czym trudno mi dostosować się do Twojej specyfikacji:

Chciałbym znaleźć wszystkie rekordy dla wszystkich użytkowników, którzy mają więcej niż jedną płatność dziennie z tym samym numerem konta ... Dodatkowo powinien istnieć filtr, który liczy tylko rekordy z innym kodem pocztowym.

Więc przyjąłem dosłowną interpretację.

Poniższe informacje są bardziej szczegółowe, ale mogą być łatwiejsze do zrozumienia i dzięki temu w utrzymaniu (użyłem CTE dla tabeli, PAYMENT_TALLIESale może to być 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
źródło
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
źródło