MySQL: Sử dụng hàm nhóm không hợp lệ


104

Tôi đang sử dụng MySQL. Đây là giản đồ của tôi:

Nhà cung cấp ( sid: số nguyên , sname: chuỗi, chuỗi địa chỉ)

Các phần ( pid: integer , pname: string, color: string)

Danh mục ( sid: số nguyên, pid: số nguyên , chi phí: thực)

(các khóa chính được in đậm)

Tôi đang cố gắng viết một truy vấn để chọn tất cả các bộ phận được làm bởi ít nhất hai nhà cung cấp:

-- 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
);

Trước hết, tôi thậm chí đang đi về điều này một cách đúng đắn?

Thứ hai, tôi gặp lỗi này:

1111 - Sử dụng chức năng nhóm không hợp lệ

Tôi đang làm gì sai?

Câu trả lời:


173

Bạn cần sử dụng HAVING, không phải WHERE.

Sự khác biệt là: WHEREmệnh đề lọc các hàng mà MySQL chọn. Sau đó, MySQL nhóm các hàng lại với nhau và tổng hợp các số cho COUNThàm của bạn .

HAVINGcũng giống như WHERE, chỉ có nó sẽ xảy ra sau khi các COUNTgiá trị đã được tính toán, vì vậy nó sẽ làm việc như bạn mong đợi. Viết lại truy vấn con của bạn thành:

(                  -- 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
Ngoài ra nếu GROUP BY được sử dụng, CÓ nên sau GROUP BY
Viacheslav

1
Ngoài ra, GROUP BY cần phải có trước khi CÓ .... Lẽ ra phải đọc bình luận của Bandolero: D
Andrew

8

Đầu tiên, lỗi bạn gặp phải là do nơi bạn đang sử dụng COUNThàm - bạn không thể sử dụng hàm tổng hợp (hoặc nhóm) trongWHERE mệnh đề.

Thứ hai, thay vì sử dụng một truy vấn con, chỉ cần nối bảng với chính nó:

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

Mà tôi tin rằng chỉ nên trả về các hàng có ít nhất hai hàng tồn tại giống nhau pidnhưng có ít nhất 2 sids. Để đảm bảo bạn chỉ nhận lại một hàng cho mỗi hàng, pidtôi đã áp dụng một điều khoản nhóm.


Có thể tôi thậm chí không cần tham gia? (xem câu trả lời cập nhật của tôi, nơi tôi cung cấp một giải pháp khả thi.)
Nick Heiner

@Rosarch, tôi nghĩ bạn sẽ muốn sử dụng COUNT(DISTINCT sid)trong truy vấn cập nhật của mình.
Mark Elliot

Không phải sidlúc nào cũng phải khác biệt, bởi vì sidpidcùng nhau tạo thành một khóa chính cho Catalog?
Nick Heiner
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.