Counting results from multiple tables with same column
I have a system where, essentially, users are able to put in 3 different pieces of information: a tip, a comment, and a vote. These pieces of information are saved to 3 different tables. The linking column of each table is the user ID. I want to do a query to determine if the user has any pieces of information at all, of any of the three types. I'm trying to do it in a single query, but it's coming out totally wrong. Here's what I'm working with now:
SELECT DISTINCT
*
FROM tips T
LEFT JOIN comments C ON T.user_id = C.user_id
LEFT JOIN votes V ON T.user_id = V.user_id
WHERE T.user_id = 1
This seems to only be getting the tips, duplicated for as many votes or comments there are, even if the votes or comments weren't made by the specified user_id.
I only need a single number in return, not individual counts of each type. I basically want a sum of the number of tips, comments, and votes saved under that user_id, but I don't want to do three queries.
Anyone have any ideas?
Edit: Actually, I don't even technically need an actual count, I just ne开发者_运维知识库ed to know if there are any rows in any of those three tables with that user_id.
Edit 2: I almost have it with this:
SELECT
COUNT(DISTINCT T.tip_id),
COUNT(DISTINCT C.tip_id),
COUNT(DISTINCT V.tip_id)
FROM tips T
LEFT JOIN comments C ON T.user_id = C.user_id
LEFT JOIN votes V ON T.user_id = V.user_id
WHERE T.user_id = 1
I'm testing with user_id 1 (me). I've made 11 tips, voted 4 times, and made no comments. My return is a row with 3 columns: 11, 0, 4. That's the proper count. However, I tested it with a user that hasn't made any tips or comments, but has voted 3 times, that returned 0 for all counts, it should have returned: 0, 0, 3.
The problem that I'm having seems to be that if the table that I'm using for the WHERE clause doesn't have any rows from that user_id, then I get 0 across the board, even if the other tables DO have rows with that user_id. I could use this query:
SELECT
(SELECT COUNT(*) FROM tips WHERE user_id = 2) +
(SELECT COUNT(*) FROM comments WHERE user_id = 2) +
(SELECT COUNT(*) FROM votes WHERE user_id = 2) AS total
But I really wanted to avoid running multiple queries, even if they're subqueries like this.
UPDATE
Thanks to ace, I figured this out:
SELECT
(COUNT(DISTINCT T.tip_id) + COUNT(DISTINCT C.tip_id) + COUNT(DISTINCT V.tip_id)) AS total
FROM users U
LEFT JOIN tips T ON U.user_id = T.user_id
LEFT JOIN votes V ON U.user_id = V.user_id
LEFT JOIN comments C ON U.user_id = C.user_id
WHERE U.user_id = 4
the users table contains the actual information bout the user including, obviously, the user id. I used the user table as the parent, since I could be 100% sure that the user would be present in that table, even if they weren't in the other tables. I got the proper count that I wanted with this query!
As I understand your question. You want to count the total comments + tips + votes for each user. Though is not really clear to me take a look at below query. I added columns for details this is a cross tabs query as someone teach me.
EDITED QUERY:
SELECT
COALESCE(COALESCE(t2.tips,0) + COALESCE(c2.comments,0) + COALESCE(v2.votes,0)) AS `Totals`
FROM parent p
LEFT JOIN (SELECT t.user_id, COUNT(t.tip_id) AS tips FROM tips t GROUP BY t.user_id) t2
ON p.user_id = t2.user_id
LEFT JOIN (SELECT c.user_id, COUNT(c.tip_id) AS comments FROM comments c GROUP BY c.user_id) c2
ON p.user_id = c2.user_id
LEFT JOIN (SELECT v.user_id, COUNT(v.tip_id) AS votes FROM votes v GROUP BY v.user_id) v2
ON p.user_id = v2.user_id
WHERE p.user_id = 1;
Note: This used a parent table in order to get the result of a table which doesn't in other table.
The reason why I use a sub-query in my JOIN is to create a virtual table that will get the sum of tip_id for each table. Also I'm having problem with the DISTINCT
using the same query of yours, so I end up with this query.
I know you prefer not using sub-queries, but I failed without a sub-query. For now this is all I can.
精彩评论