Truy vấn của bạn sẽ hoạt động - ngoại trừ việc bạn đang gặp phải xung đột đặt tên hoặc chỉ nhầm lẫn với cột đầu ra (CASE
biểu thức) với cột nguồn result
, có nội dung khác.
...
GROUP BY model.name, attempt.type, attempt.result
...
Bạn cần GROUP BY
CASE
của bạn biểu thức thay vì cột nguồn của bạn:
...
GROUP BY model.name, attempt.type
, CASE WHEN attempt.result = 0 THEN 0 ELSE 1 END
...
Hoặc cung cấp bí danh cột khác với bất kỳ tên cột nào trong FROM
danh sách - hoặc nếu không cột đó sẽ được ưu tiên:
SELECT ...
, CASE WHEN attempt.result = 0 THEN 0 ELSE 1 END AS result1
...
GROUP BY model.name, attempt.type, result1
...
Tiêu chuẩn SQL khá đặc biệt về mặt này. Trích dẫn hướng dẫn sử dụng tại đây:
Tên của cột đầu ra có thể được sử dụng để tham chiếu đến giá trị của cột trong
ORDER BY
vàGROUP BY
các mệnh đề, nhưng không có trongWHERE
hoặcHAVING
mệnh đề; ở đó bạn phải viết ra biểu thức để thay thế.
Và:
Nếu một
ORDER BY
biểu thức là một tên đơn giản phù hợp với cả tên cột đầu ra và tên cột đầu vào,ORDER BY
sẽ giải thích nó thông qua tên cột đầu ra. Điều này ngược lại với lựa chọnGROUP BY
sẽ làm cho trong cùng một tình huống. Sự mâu thuẫn này được tạo ra để tương thích với tiêu chuẩn SQL.
In đậm nhấn mạnh của tôi.
Có thể tránh được những xung đột này bằng cách sử dụng tham chiếu theo vị trí (số thứ tự) trong GROUP BY
và ORDER BY
, tham chiếu đến các mục trong SELECT
danh sách từ trái sang phải. Xem giải pháp bên dưới.
Hạn chế là điều này có thể khó đọc hơn và dễ bị chỉnh sửa trong SELECT
danh sách (người ta có thể quên điều chỉnh các tham chiếu vị trí cho phù hợp).
Nhưng bạn không không phải thêm cột day
vào GROUP BY
mệnh đề, miễn là nó giữ một giá trị không đổi (CURRENT_DATE-1
).
Được viết lại và đơn giản hóa với cú pháp JOIN phù hợp và các tham chiếu vị trí, nó có thể trông như thế này:
SELECT m.name
, a.type
, CASE WHEN a.result = 0 THEN 0 ELSE 1 END AS result
, CURRENT_DATE - 1 AS day
, count(*) AS ct
FROM attempt a
JOIN prod_hw_id p USING (hard_id)
JOIN model m USING (model_id)
WHERE ts >= '2013-11-06 00:00:00'
AND ts < '2013-11-07 00:00:00'
GROUP BY 1,2,3
ORDER BY 1,2,3;
Cũng lưu ý rằng tôi đang tránh tên cột time
. Đó là một từ dành riêng và không bao giờ được sử dụng làm định danh. Ngoài ra, "thời gian" của bạn rõ ràng là một timestamp
hoặc day
, vì vậy điều đó hơi gây hiểu lầm.