MySQL: การใช้ฟังก์ชันกลุ่มไม่ถูกต้อง


105

ฉันใช้ MySQL นี่คือสคีมาของฉัน:

ซัพพลายเออร์ ( sid: integer , sname: string, address string)

ส่วนต่างๆ ( pid: integer , pname: string, color: string)

แค็ตตาล็อก ( sid: integer, pid: integer , cost: real)

(คีย์หลักเป็นตัวหนา)

ฉันพยายามเขียนแบบสอบถามเพื่อเลือกชิ้นส่วนทั้งหมดที่สร้างโดยซัพพลายเออร์อย่างน้อยสองราย:

-- Find the pids of parts supplied by at least two different suppliers.
SELECT c1.pid                      -- select the pid
FROM Catalog AS c1                 -- from the Catalog table
WHERE c1.pid IN (                  -- where that pid is in the set:
    SELECT c2.pid                  -- of pids
    FROM Catalog AS c2             -- from catalog
    WHERE c2.pid = c1.pid AND COUNT(c2.sid) >= 2 -- where there are at least two corresponding sids
);

ก่อนอื่นฉันไปถูกทางแล้วหรือยัง?

ประการที่สองฉันได้รับข้อผิดพลาดนี้:

1111 - การใช้ฟังก์ชันกลุ่มไม่ถูกต้อง

ผมทำอะไรผิดหรือเปล่า?

คำตอบ:


175

คุณจำเป็นต้องใช้ไม่ได้HAVINGWHERE

ความแตกต่างคือ: WHEREประโยคจะกรองแถวที่ MySQL เลือก จากนั้น MySQL จะจัดกลุ่มแถวเข้าด้วยกันและรวมตัวเลขสำหรับCOUNTฟังก์ชันของคุณ

HAVINGเป็นเหมือนWHEREเพียง แต่มันเกิดขึ้นหลังจากที่COUNTค่าได้รับการคำนวณดังนั้นจึงจะทำงานตามที่คุณคาดหวัง เขียนข้อความค้นหาย่อยของคุณใหม่เป็น:

(                  -- where that pid is in the set:
SELECT c2.pid                  -- of pids
FROM Catalog AS c2             -- from catalog
WHERE c2.pid = c1.pid
HAVING COUNT(c2.sid) >= 2)

25
นอกจากนี้หากใช้ GROUP BY ควร HAVING หลัง GROUP BY
Viacheslav

1
นอกจากนี้ GROUP BY ต้องมาก่อน HAVING .... ควรอ่านความคิดเห็นของ Bandolero: D
Andrew

9

ประการแรกข้อผิดพลาดที่คุณได้รับเกิดจากที่ที่คุณใช้COUNTฟังก์ชันคุณไม่สามารถใช้ฟังก์ชันรวม (หรือกลุ่ม) ในWHEREประโยคคำสั่ง

ประการที่สองแทนที่จะใช้แบบสอบถามย่อยเพียงแค่เข้าร่วมตารางกับตัวเอง:

SELECT a.pid 
FROM Catalog as a LEFT JOIN Catalog as b USING( pid )
WHERE a.sid != b.sid
GROUP BY a.pid

ซึ่งฉันเชื่อว่าควรส่งคืนเฉพาะแถวที่มีอย่างน้อยสองแถวที่มีแถวเดียวกันpidแต่มีอย่างน้อย 2 sidวินาที เพื่อให้แน่ใจว่าคุณจะกลับมาเพียงแถวเดียวต่อpidฉันได้ใช้ประโยคการจัดกลุ่ม


เป็นไปได้ไหมที่ฉันไม่จำเป็นต้องเข้าร่วม (ดูคำตอบที่อัปเดตของฉันซึ่งฉันให้วิธีแก้ปัญหาที่เป็นไปได้)
Nick Heiner

@Rosarch ฉันคิดว่าคุณจะต้องใช้COUNT(DISTINCT sid)ในแบบสอบถามที่อัปเดตของคุณ
Mark Elliot

ไม่sidจำเป็นต้องแตกต่างกันเสมอไปเพราะsidและpidรวมกันเป็นคีย์หลักสำหรับCatalog?
Nick Heiner
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.