开发者

Counting results from multiple tables with same column

开发者 https://www.devze.com 2023-02-24 12:32 出处:网络
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 col

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消