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.