The UNION
pair is effectively a derived table and must appear in a FROM
clause to participate in the JOIN
. Since it is in the FROM
clause now, you must SELECT
its columns, otherwise your query has no SELECT
clause at all. MySQL's syntax is lenient, but not so lenient as to permit a missing SELECT
clause.
/* SELECT the cols produced by the UNION */
SELECT
a.`num`,
a.`post_uuid`,
a.`mode`,
/* And other columns from `posts` if needed */
b.`something`,
b.`something_else`,
b.`some_other_thing`
/* UNIONs are a derived table, belonging in FROM */
FROM (
(
SELECT COUNT(*) as num, post_uuid, 'upvotes' AS 'mode'
FROM post_votes a
WHERE a.vote = 1
GROUP BY post_uuid
)
UNION
(
SELECT COUNT(*) num, post_uuid, 'downvotes' AS 'mode'
FROM post_votes a
WHERE a.vote = 1
GROUP BY post_uuid
)
) a
LEFT JOIN posts b ON a.post_uuid = b.post_uuid
Looking over this, I believe you can simplify away the UNION
by using a SUM(CASE)
aggregate pattern:
SELECT
b.post_uuid,
SUM(CASE WHEN a.vote = 1 THEN 1 ELSE 0 END) AS upvotes,
/* Assume -1 for downvotes? */
SUM(CASE WHEN a.vote = -1 THEN 1 ELSE 0 END) AS downvotes
FROM
posts b
LEFT JOIN post_votes a ON a.post_uuid = b.post_uuid
GROUP BY b.post_uuid