แบบสอบถาม SQL สำหรับการค้นหาระเบียนที่นับ> 1


176

PAYMENTผมมีตารางชื่อ ภายในตารางนี้ฉันมี ID ผู้ใช้หมายเลขบัญชีรหัสไปรษณีย์และวันที่ ฉันต้องการค้นหาระเบียนทั้งหมดสำหรับผู้ใช้ทั้งหมดที่มีการชำระเงินมากกว่าหนึ่งรายการต่อวันด้วยหมายเลขบัญชีเดียวกัน

อัปเดต:นอกจากนี้ควรมีตัวกรองมากกว่านับเฉพาะระเบียนที่มีรหัสไปรษณีย์แตกต่างกัน

นี่เป็นลักษณะของตาราง:

| user_id | บัญชี _no | zip | วันที่ |
| 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 |

ผลลัพธ์ควรมีลักษณะเช่นนี้:

| user_id | นับ |
| 1 | 2 |

คุณจะแสดงสิ่งนี้ในแบบสอบถาม SQL ได้อย่างไร? ฉันคิดว่าเข้าร่วมด้วยตนเอง แต่ด้วยเหตุผลบางอย่างที่ฉันนับผิด

คำตอบ:


345

ใช้ส่วนคำสั่งHAVINGและ GROUP ตามฟิลด์ที่ทำให้แถวไม่ซ้ำกัน

ด้านล่างจะพบว่า

ผู้ใช้ทั้งหมดที่มีการชำระเงินมากกว่าหนึ่งครั้งต่อวันด้วยหมายเลขบัญชีเดียวกัน

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

อัปเดต หากคุณต้องการรวมเฉพาะที่มี ZIP ที่แตกต่างกันคุณสามารถรับชุดที่แตกต่างก่อนจากนั้นจึงทำการ 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
การแจ้งให้ทราบในผลลัพธ์ของเขา2มีจำนวน4- คุณจะต้องยกเลิกการAccount_noจัดกลุ่มที่ฉันคิดว่า
JNK

ไม่ต้องรอฉันคิดว่าต้นฉบับถูก "ผู้ใช้ทั้งหมดที่มีการชำระเงินมากกว่าหนึ่งครั้งต่อวันด้วยหมายเลขบัญชีเดียวกัน"
Conrad Frix

มันบอกว่า แต่ผลลัพธ์ของเขาแสดงเป็นอย่างอื่น อาจมีทั้งสองรุ่นพร้อมโน้ต
JNK

ขอบคุณสำหรับคำตอบของคุณ ฉันคิดว่าควรทำ หากตอนนี้ฉันต้องการเพิ่มตัวกรองอื่นที่ตรวจสอบว่ารหัสไปรษณีย์การเรียกเก็บเงิน (ตารางเดียวกันคอลัมน์ที่แตกต่างกัน) จะแตกต่างกันในวันเดียวกันฉันจะแก้ไขแบบสอบถามนี้อย่างไร
Benjamin Muschko

ฉันไม่สามารถแก้ไขผลลัพธ์ตัวอย่างได้ หากเราลบบัญชีเราจะได้สามแถว หากเราทิ้งทั้งวันที่และบัญชีเราจะได้สองแถว 1,3 และ 2,4 ดังนั้นฉันจะไปข้างหน้าและเชื่อใจคำศัพท์มากกว่าผลลัพธ์
Conrad Frix

43

ลองใช้แบบสอบถามนี้:

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

4
เรียบร้อย แต่นี่ไม่ได้ตอบคำถาม
Lambart

4

ฉันจะไม่แนะนำHAVINGคำหลักสำหรับมือใหม่ แต่ก็มีไว้สำหรับวัตถุประสงค์ดั้งเดิมเท่านั้น

ฉันไม่ชัดเจนในสิ่งที่เป็นกุญแจสำคัญสำหรับตารางนี้ (เป็นปกติอย่างสมบูรณ์ฉันสงสัย?) ดังนั้นฉันคิดว่ามันยากที่จะปฏิบัติตามข้อกำหนดของคุณ:

ฉันต้องการค้นหาระเบียนทั้งหมดสำหรับผู้ใช้ทั้งหมดที่มีการชำระเงินมากกว่าหนึ่งครั้งต่อวันด้วยหมายเลขบัญชีเดียวกัน ... นอกจากนี้ควรมีตัวกรองมากกว่านับเฉพาะระเบียนที่มีรหัสไปรษณีย์แตกต่างกัน

ดังนั้นฉันจึงตีความตามตัวอักษร

ต่อไปนี้เป็น verbose มากขึ้น แต่อาจจะเข้าใจง่ายกว่าและดังนั้นจึงรักษาไว้ (ฉันใช้CTEสำหรับตารางPAYMENT_TALLIESแต่อาจเป็น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;
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.