Permintaan SQL untuk menemukan catatan di mana jumlah> 1

177

Saya punya tabel bernama PAYMENT. Dalam tabel ini saya memiliki ID pengguna, nomor akun, kode ZIP dan tanggal. Saya ingin menemukan semua catatan untuk semua pengguna yang memiliki lebih dari satu pembayaran per hari dengan nomor akun yang sama.

UPDATE: Selain itu, harus ada filter daripada hanya menghitung catatan yang kode ZIP-nya berbeda.

Seperti inilah tabelnya:

| user_id | account_no | zip | tanggal |
| 1 | 123 | 55555 | 12-DES-09 |
| 1 | 123 | 66666 | 12-DES-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 |

Hasilnya akan terlihat mirip dengan ini:

| user_id | hitung |
| 1 | 2 |

Bagaimana Anda mengekspresikannya dalam query SQL? Saya berpikir untuk bergabung sendiri tetapi karena alasan tertentu hitungan saya salah.

Benjamin Muschko
sumber

Jawaban:

346

Gunakan klausa HAVING dan GROUP By the field yang membuat baris menjadi unik

Di bawah ini akan ditemukan

semua pengguna yang memiliki lebih dari satu pembayaran per hari dengan nomor akun yang sama

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

Pembaruan Jika Anda ingin hanya menyertakan yang memiliki ZIP yang berbeda, Anda bisa mendapatkan set yang berbeda terlebih dahulu dan kemudian melakukan Anda 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
sumber
1
Perhatikan dalam hasil-hasilnya 2memiliki hitungan 4- Anda akan ingin membuang Account_nopengelompokan yang saya pikir.
JNK
Tidak tunggu, saya pikir aslinya benar "semua pengguna yang memiliki lebih dari satu pembayaran per hari dengan nomor akun yang sama."
Conrad Frix
ia mengatakan itu tetapi hasilnya menunjukkan sebaliknya. Mungkin memiliki kedua versi dengan catatan.
JNK
Terima kasih atas tanggapan Anda. Saya pikir itu harus dilakukan. Jika sekarang saya ingin menambahkan filter lain yang memeriksa apakah kode ZIP penagihan (tabel yang sama, kolom yang berbeda) berbeda untuk tanggal yang sama bagaimana cara memodifikasi kueri ini?
Benjamin Muschko
Saya tidak bisa menyelesaikan output sampel. Jika kami menjatuhkan Akun, kami akan mendapatkan tiga baris. Jika kami mencabut tanggal dan akun, kami akan mendapatkan dua baris 1,3 dan 2,4. Jadi saya akan terus maju dan percaya kata-kata atas output
Conrad Frix
43

Coba kueri ini:

SELECT column_name
  FROM table_name
 GROUP BY column_name
HAVING COUNT(column_name) = 1;
pengguna4019456
sumber
4
rapi, tetapi ini tidak menjawab pertanyaan
Lambart
4

Saya tidak akan merekomendasikan HAVINGkata kunci untuk pemula, ini pada dasarnya untuk tujuan warisan .

Saya tidak jelas tentang apa kunci untuk tabel ini (apakah ini dinormalisasi sepenuhnya , saya bertanya-tanya?), Akibatnya saya merasa sulit untuk mengikuti spesifikasi Anda:

Saya ingin menemukan semua catatan untuk semua pengguna yang memiliki lebih dari satu pembayaran per hari dengan nomor akun yang sama ... Selain itu, harus ada filter daripada hanya menghitung catatan yang kode ZIP-nya berbeda.

Jadi saya mengambil interpretasi literal.

Berikut ini lebih verbose tetapi bisa lebih mudah dipahami dan karenanya dipertahankan (Saya sudah menggunakan CTE untuk tabel PAYMENT_TALLIEStetapi bisa menjadi 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
              );
suatu hari nanti
sumber
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
sumber