Tới UNION
các hàng kết quả của cả ba truy vấn và sau đó chọn 5 hàng có số tiền amount
cao nhất :
(SELECT event_id, count(*) AS amount
FROM pageview
GROUP BY event_id
ORDER BY pageviews DESC, rand()
LIMIT 1000)
UNION ALL
(SELECT event_id, count(*)
FROM upvote
GROUP BY event_id
ORDER BY upvotes DESC, rand()
LIMIT 1000)
UNION ALL
(SELECT event_id, count(*)
FROM attending
GROUP BY event_id
ORDER BY attendants DESC, rand()
LIMIT 1000)
ORDER BY 2 DESC
LIMIT 5;
UNION ALL
để giữ các bản sao.
Để thêm số lượng cho mọi event_id
:
SELECT event_id, sum(amount) AS total
FROM (
(SELECT event_id, count(*) AS amount
FROM pageview
GROUP BY event_id
ORDER BY pageviews DESC, rand()
LIMIT 1000)
UNION ALL
(SELECT event_id, count(*)
FROM upvote
GROUP BY event_id
ORDER BY upvotes DESC, rand()
LIMIT 1000)
UNION ALL
(SELECT event_id, count(*)
FROM attending
GROUP BY event_id
ORDER BY attendants DESC, rand()
LIMIT 1000)
) x
GROUP BY 1
ORDER BY sum(amount) DESC
LIMIT 5;
Phần khó ở đây là không phải mọi event_id
sẽ có mặt trong cả ba truy vấn cơ sở. Vì vậy, hãy cẩn thận rằng một JOIN
không mất hàng hoàn toàn và các bổ sung không xuất hiện NULL
.
Sử dụng UNION ALL
, không phải UNION
. Bạn không muốn xóa các hàng giống hệt nhau, bạn muốn thêm chúng vào.
x
là bí danh bảng và viết tắt của AS x
. Yêu cầu đối với một truy vấn con phải có tên. Có thể là bất kỳ tên nào khác ở đây.
Tính năng SOL FULL OUTER JOIN
không được triển khai trong MySQL (lần trước tôi đã kiểm tra), vì vậy bạn phải thực hiện với UNION
. FULL OUTER JOIN
sẽ kết hợp tất cả ba truy vấn cơ sở mà không bị mất hàng.
Trả lời cho câu hỏi tiếp theo
SELECT event_id, sum(amount) AS total
FROM (
(SELECT event_id, count(*) / 100 AS amount
FROM pageview ... )
UNION ALL
(SELECT event_id, count(*) * 5
FROM upvote ... )
UNION ALL
(SELECT event_id, count(*) * 10
FROM attending ... )
) x
GROUP BY 1
ORDER BY sum(amount) DESC
LIMIT 5;
Hoặc, để sử dụng số lượng cơ sở theo nhiều cách:
SELECT event_id
,sum(CASE source
WHEN 'p' THEN amount / 100
WHEN 'u' THEN amount * 5
WHEN 'a' THEN amount * 10
ELSE 0
END) AS total
FROM (
(SELECT event_id, 'p'::text AS source, count(*) AS amount
FROM pageview ... )
UNION ALL
(SELECT event_id, 'u'::text, count(*)
FROM upvote ... )
UNION ALL
(SELECT event_id, 'a'::text, count(*)
FROM attending ... )
) x
GROUP BY 1
ORDER BY 2 DESC
LIMIT 5;