Consulta SQL para encontrar registros donde cuenta> 1

176

Tengo una tabla llamada PAYMENT. Dentro de esta tabla tengo una identificación de usuario, un número de cuenta, un código postal y una fecha. Me gustaría encontrar todos los registros de todos los usuarios que tienen más de un pago por día con el mismo número de cuenta.

ACTUALIZACIÓN: Además, debe haber un filtro que solo cuente los registros cuyo código postal es diferente.

Así es como se ve la tabla:

El | ID_usuario | cuenta_no | zip | fecha |
El | 1 | 123 | 55555 | 12-DIC-09 |
El | 1 | 123 | 66666 | 12-DIC-09 |
El | 1 | 123 | 55555 | 13-DIC-09 |
El | 2 | 456 77777 | 14-DIC-09 |
El | 2 | 456 77777 | 14-DIC-09 |
El | 2 | 789 77777 | 14-DIC-09 |
El | 2 | 789 77777 | 14-DIC-09 |

El resultado debería ser similar a esto:

El | ID_usuario | contar |
El | 1 | 2 |

¿Cómo expresarías esto en una consulta SQL? Estaba pensando en unirme, pero por alguna razón mi cuenta está equivocada.

Benjamin Muschko
fuente

Respuestas:

345

Use la cláusula HAVING y GROUP por los campos que hacen que la fila sea única

El siguiente encontrará

todos los usuarios que tienen más de un pago por día con el mismo número de cuenta

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

Actualizar Si solo desea incluir aquellos que tienen un ZIP distinto, primero puede obtener un conjunto distinto y luego realizarlo 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
fuente
1
Observe que en sus resultados 2se cuenta 4: Deseará descartar la Account_noagrupación, creo.
JNK
No espere, creo que el original tenía razón "todos los usuarios que tienen más de un pago por día con el mismo número de cuenta".
Conrad Frix
dice eso pero sus resultados muestran lo contrario. Quizás tenga ambas versiones con una nota.
JNK
Gracias por sus respuestas Creo que eso debería hacerlo. Si ahora quisiera agregar otro filtro que verifique si el código postal de facturación (misma tabla, columna diferente) es diferente para la misma fecha, ¿cómo modificaría esta consulta?
Benjamin Muschko
No puedo resolver la salida de muestra. Si dejamos caer la cuenta, obtendríamos tres filas. Si eliminamos tanto la fecha como la cuenta, obtendríamos dos filas 1,3 y 2,4. Así que voy a seguir adelante y confiar en las palabras sobre la salida
Conrad Frix
43

Prueba esta consulta:

SELECT column_name
  FROM table_name
 GROUP BY column_name
HAVING COUNT(column_name) = 1;
usuario4019456
fuente
44
ordenado, pero esto no responde a la pregunta
Lambart
4

No recomendaría la HAVINGpalabra clave para los novatos, es esencialmente para fines heredados .

No tengo claro cuál es la clave de esta tabla ( me pregunto si está completamente normalizada ), por lo tanto, me resulta difícil seguir su especificación:

Me gustaría encontrar todos los registros de todos los usuarios que tienen más de un pago por día con el mismo número de cuenta ... Además, debe haber un filtro que solo cuente los registros cuyo código postal es diferente.

Entonces tomé una interpretación literal.

Lo siguiente es más detallado pero podría ser más fácil de entender y, por lo tanto, mantener (he usado un CTE para la tabla PAYMENT_TALLIESpero podría ser 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
              );
un día cuando
fuente
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
fuente