Truy vấn SQL để tìm bản ghi trong đó đếm> 1


176

Tôi có một bảng tên PAYMENT. Trong bảng này, tôi có ID người dùng, số tài khoản, mã ZIP và ngày. Tôi muốn tìm tất cả các hồ sơ cho tất cả người dùng có nhiều hơn một khoản thanh toán mỗi ngày với cùng một số tài khoản.

CẬP NHẬT: Ngoài ra, cần có một bộ lọc hơn là chỉ đếm các bản ghi có mã ZIP khác nhau.

Đây là cách bảng trông như thế nào:

| user_id | tài khoản_no | zip | ngày |
| 1 | 123 | 55555 | 12 tháng 12-ngày 09 |
| 1 | 123 | 66666 | 12 tháng 12-ngày 09 |
| 1 | 123 | 55555 | 13-THÁNG 12-09 |
| 2 | 456 | 77777 | 14-THÁNG 12-09 |
| 2 | 456 | 77777 | 14-THÁNG 12-09 |
| 2 | 789 | 77777 | 14-THÁNG 12-09 |
| 2 | 789 | 77777 | 14-THÁNG 12-09 |

Kết quả sẽ trông giống như thế này:

| user_id | đếm |
| 1 | 2 |

Làm thế nào bạn sẽ thể hiện điều này trong một truy vấn SQL? Tôi đã suy nghĩ tự tham gia nhưng vì một số lý do, tính của tôi là sai.

Câu trả lời:


344

Sử dụng mệnh đề HAVING và NHÓM Theo các trường làm cho hàng duy nhất

Dưới đây sẽ tìm thấy

tất cả người dùng có nhiều khoản thanh toán mỗi ngày với cùng số tài khoản

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

Cập nhật Nếu bạn muốn chỉ bao gồm những người có ZIP riêng biệt, trước tiên bạn có thể nhận được một bộ riêng biệt và sau đó thực hiện cho bạn 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
Lưu ý trong kết quả của anh ta 2có một số lượng 4- Bạn sẽ muốn loại bỏ Account_nonhóm tôi nghĩ.
JNK

Không chờ đợi, tôi nghĩ rằng bản gốc đã đúng "tất cả người dùng có nhiều hơn một khoản thanh toán mỗi ngày với cùng một số tài khoản."
Conrad Frix

Nó nói rằng nhưng kết quả của ông cho thấy khác. Có thể có cả hai phiên bản với một ghi chú.
JNK

Cảm ơn câu trả lời của bạn. Tôi nghĩ rằng nên làm điều đó. Nếu bây giờ tôi muốn thêm một bộ lọc khác để kiểm tra xem mã ZIP thanh toán (cùng bảng, cột khác) có khác nhau trong cùng một ngày không, tôi sẽ sửa đổi truy vấn này như thế nào?
Benjamin Muschko

Tôi không thể giải quyết đầu ra mẫu. Nếu chúng tôi bỏ Tài khoản, chúng tôi sẽ nhận được ba hàng. Nếu chúng tôi bỏ cả ngày và tài khoản, chúng tôi sẽ nhận được hai hàng 1,3 và 2,4. Vì vậy, tôi sẽ tiếp tục và tin tưởng vào các từ trên đầu ra
Conrad Frix

43

Hãy thử truy vấn này:

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

4
gọn gàng, nhưng điều này không trả lời câu hỏi
Lambart

4

Tôi sẽ không đề xuất HAVINGtừ khóa cho người mới, nó chủ yếu dành cho mục đích kế thừa .

Tôi không rõ chìa khóa của bảng này là gì (nó có được chuẩn hóa hoàn toàn không , tôi tự hỏi?), Do đó tôi cảm thấy khó khăn khi làm theo đặc điểm kỹ thuật của bạn:

Tôi muốn tìm tất cả các bản ghi cho tất cả người dùng có nhiều hơn một khoản thanh toán mỗi ngày với cùng một số tài khoản ... Ngoài ra, nên có một bộ lọc hơn là chỉ đếm các bản ghi có mã ZIP khác nhau.

Vì vậy, tôi đã thực hiện một giải thích theo nghĩa đen.

Sau đây dài dòng hơn nhưng có thể dễ hiểu hơn và do đó duy trì (Tôi đã sử dụng CTE cho bảng PAYMENT_TALLIESnhưng nó có thể là 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;
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.