Query SQL per la ricerca di record in cui conta> 1


177

Ho un tavolo chiamato PAYMENT. All'interno di questa tabella ho un ID utente, un numero di conto, un codice postale e una data. Vorrei trovare tutti i record per tutti gli utenti che hanno più di un pagamento al giorno con lo stesso numero di conto.

AGGIORNAMENTO: Inoltre, dovrebbe esserci un filtro che conta solo i record il cui codice postale è diverso.

Ecco come appare la tabella:

| id_utente | account_no | zip | data |
| 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 |

Il risultato dovrebbe essere simile al seguente:

| id_utente | contare |
| 1 | 2 |

Come lo esprimeresti in una query SQL? Stavo pensando di unirmi, ma per qualche ragione il mio conto è sbagliato.

Risposte:


346

Usa la clausola HAVING e GROUP By i campi che rendono unica la riga

Di seguito troverai

tutti gli utenti che hanno più di un pagamento al giorno con lo stesso numero di conto

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

Aggiorna Se vuoi includere solo quelli che hanno un ZIP distinto, puoi prima ottenere un set distinto e poi eseguirti 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
Si noti che nei suoi risultati 2c'è un conteggio 4: vorrai scartare il Account_noraggruppamento che penso.
JNK,

No aspetta, penso che l'originale fosse giusto "tutti gli utenti che hanno più di un pagamento al giorno con lo stesso numero di conto".
Conrad Frix,

dice questo, ma i suoi risultati mostrano il contrario. Forse hanno entrambe le versioni con una nota.
JNK

Grazie per le tue risposte Penso che dovrebbe farlo. Se ora volessi aggiungere un altro filtro che controlla se il codice postale di fatturazione (stessa tabella, colonna diversa) è diverso per la stessa data, come dovrei modificare questa query?
Benjamin Muschko

Non riesco a risolvere l'output di esempio. Se abbandoniamo l'account, otterremmo tre righe. Se cadiamo sia la data che l'account otterremmo due righe 1,3 e 2,4. Quindi vado avanti e mi fido delle parole sull'output
Conrad Frix,

43

Prova questa query:

SELECT column_name
  FROM table_name
 GROUP BY column_name
HAVING COUNT(column_name) = 1;

4
pulito, ma questo non risponde alla domanda
Lambart

4

Non consiglierei la HAVINGparola chiave per i neofiti, è essenzialmente per scopi legacy .

Non sono chiaro su quale sia la chiave di questa tabella (è completamente normalizzata , mi chiedo?), Di conseguenza trovo difficile seguire le vostre specifiche:

Vorrei trovare tutti i record per tutti gli utenti che hanno più di un pagamento al giorno con lo stesso numero di conto ... Inoltre, ci dovrebbe essere un filtro che conta solo i record il cui codice postale è diverso.

Quindi ho preso un'interpretazione letterale.

Quanto segue è più dettagliato ma potrebbe essere più facile da capire e quindi mantenere (ho usato un CTE per la tabella PAYMENT_TALLIESma potrebbe essere un 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;
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.