Reputation: 8189
By using COALESCE, I can create a temporary variable called comment_votes like so:
SELECT comments.*, COALESCE(rs_reputations.value, 0) AS comment_votes FROM `comments`
LEFT JOIN rs_reputations ON comments.id = rs_reputations.target_id AND
rs_reputations.target_type = 'Comment' AND rs_reputations.reputation_name =
'comment_votes' AND rs_reputations.active = 1 WHERE (impression_id = 1)
I want to create a second variable called impression_votes in the came query. I attempted to do this with:
SELECT comments.*, COALESCE(rs_reputations.value, 0) AS comment_votes
FROM 'comments'
LEFT JOIN rs_reputations ON
comments.id = rs_reputations.target_id AND
rs_reputations.target_type = 'Comment' AND
rs_reputations.reputation_name = 'comment_votes' AND
rs_reputations.active = 1
SELECT comments.*, COALESCE(rs_reputations.value, 0) AS impression_votes
FROM 'comments'
LEFT JOIN rs_reputations ON
comments.id = rs_reputations.target_id AND
rs_reputations.target_type = 'Comment' AND
rs_reputations.reputation_name = 'impression_votes' AND
rs_reputations.active = 1
WHERE
This leads to the error:
You have an error in your SQL syntax
Is what I'm attempting even possible? If so, I seem to be bridging the two SELECT/COALESCE statements improperly. How should I write this?
Upvotes: 1
Views: 2852
Reputation: 91480
The MySQL COALESCE function is actually an inbuilt function that returns the first non-null value - it's not a variable, it's a function that is actually supported across a wide variety of database systems.
For example, with the following table:
| Id | Name | Counter |
| 1 | lolcat | NULL |
| 2 | codez | 1 |
The sql statement:
SELECT Id, Name, COALESCE(counter, 0) AS NonNullCounter FROM table
will return the results:
| Id | Name | NonNullCounter |
| 1 | lolcat | 0 |
| 2 | codez | 1 |
In this instance, the NULL value has been replaced by 0.
This is useful for you as, if you don't yet have any matching rows in rs_reputations for the row in comments, the LEFT JOIN
will return NULL
for the column rs_repuations.value
, which is then replaced by 0
by COALESCE
.
If you are new to JOINs then there is a great visual guide by Jeff Atwood.
Your first query can is actually:
SELECT comments.*,
COALESCE(rs_reputations.value, 0) AS comment_votes
FROM comments
LEFT JOIN rs_reputations ON comments.id = rs_reputations.target_id
AND rs_reputations.reputation_name = 'comment_votes'
WHERE impression_id = 1;
CHOICE 1 - UNION
You have a couple of choices - you can either UNION your results together like this:
SELECT comments.*,
COALESCE(rs_reputations.value, 0) AS votes,
'comment_votes' AS vote_type
FROM comments
LEFT JOIN rs_reputations ON comments.id = rs_reputations.target_id
AND rs_reputations.reputation_name = 'comment_votes'
WHERE impression_id = 1
UNION
SELECT comments.*,
COALESCE(rs_reputations.value, 0) AS votes,
'impression_votes' as vote_type
FROM comments
LEFT JOIN rs_reputations ON comments.id = rs_reputations.target_id
AND rs_reputations.reputation_name = 'impression_votes'
WHERE impression_id = 1;
In this instance your results will look like this:
|comments_columns|votes|vote_type |
| * |12 |comment_vote |
| * |2 |impression_vote |
CHOICE 2 - JOIN ON TO THE SAME TABLE TWICE
Or you can self join onto the same table twice by using the same table name but a different alias:
SELECT comments.*,
COALESCE(CommentRep.value, 0) AS comment_votes,
COALESCE(ImpressionRep.value, 0) AS impression_votes,
FROM comments
LEFT JOIN rs_reputations AS CommentRep ON comments.id = CommentRep.target_id
AND CommentRep.reputation_name = 'comment_votes'
LEFT JOIN rs_reputations AS ImpressionRep ON comments.id = ImpressionRep.target_id
AND ImpressionRep.reputation_name = 'impression_votes'
WHERE CommentRep.impression_id = 1
AND ImpressionRep.impression_id = 1
In this instance your results will look like this:
|comments_columns|comment_votes|impression_votes|
| * |12 |0 |
| * |2 |6 |
Finally (phew) the reason you have an error in your original SQL is that you are chaining two SELECT statements together without actually relating them - the SQL doesn't really make sense in this instance as you need to logically relate them (either via a UNION or a repeated join as per above.
Upvotes: 2