Background info
System
OS:
bash$ lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description: Debian GNU/Linux 6.0.5 (squeeze)
Release: 6.0.5
Codename: squeeze
MySQL:
bash$ mysql --version
mysql Ver 14.14 Distrib 5.1.63, for debian-linux-gnu (x86_64) using readline 6.1
Database
Engine: MyISAM
Table: post_votes
mysql> describe post_votes;
+-----------+---------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+---------------------+------+-----+---------+----------------+
| id | bigint(20) unsigned | NO | PRI | NULL | auto_increment |
| post_uuid | binary(16) | YES | | NULL | |
| user_uuid | binary(16) | YES | | NULL | |
| vote | tinyint(4) | YES | | 0 | |
+-----------+---------------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)
Table: posts
mysql> describe posts;
+-------------+---------------------+------+-----+----------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+---------------------+------+-----+----------------------+----------------+
| id | bigint(20) unsigned | NO | PRI | NULL | auto_increment |
| post_uuid | binary(16) | YES | UNI | NULL | |
| owner_uuid | binary(16) | YES | | NULL | |
| created | int(10) unsigned | YES | | NULL | |
| edited | int(10) unsigned | YES | | NULL | |
| title | varchar(50) | YES | | NULL | |
| description | varchar(150) | YES | | NULL | |
| link | varchar(100) | YES | | NULL | |
| properties | varchar(20) | YES | | 00000000000000000000 | |
+-------------+---------------------+------+-----+----------------------+----------------+
9 rows in set (0.00 sec)
The Problem
I want to select posts depending on their upvote/downvote ratio. I’ve come up with a query that counts upvotes and downvotes but can’t seem to join it to the actual posts.
The working (uncomplete) query
(
SELECT COUNT(*), post_uuid, 'upvotes' AS 'mode'
FROM post_votes a
WHERE a.vote = 1
GROUP BY post_uuid
)
UNION
(
SELECT COUNT(*), post_uuid, 'downvotes' AS 'mode'
FROM post_votes a
WHERE a.vote = -1
GROUP BY post_uuid
)
The broken query
(
(
SELECT COUNT(*), post_uuid, 'upvotes' AS 'mode'
FROM post_votes a
WHERE a.vote = 1
GROUP BY post_uuid
)
UNION
(
SELECT COUNT(*), 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
What am I doing wrong? the error message I get is:
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use near 'UNION
(
SELECT COUNT(*), post_uuid, 'downvotes' AS 'mode'
The
UNIONpair is effectively a derived table and must appear in aFROMclause to participate in theJOIN. Since it is in theFROMclause now, you mustSELECTits columns, otherwise your query has noSELECTclause at all. MySQL’s syntax is lenient, but not so lenient as to permit a missingSELECTclause.Looking over this, I believe you can simplify away the
UNIONby using aSUM(CASE)aggregate pattern: