简体   繁体   中英

Count in where clause or subquery calculation in select

I have a table story , which contains an id and a title . Users can vote up or down for each story. Here is the model:

+-------+      +----------+
| Story |      |   vote   |
+-------+~~~~~~+----------+
| id    |      | id       |
| title |      | story_id |
+-------+      | type     |
               +----------+

type is a boolean . I would like to fetch stories with a difference between upvote and downvote > 1. And I also would like to know how many upvotes the story got. To sum up, this is an example of the result I'm trying to get:

+----------+---------+------------+------------+
| story_id | title   | difference | nb_upvotes |
+----------+---------+------------+------------+
| 1        | title 1 | 5          | 45         |
| 4        | title 4 | 32         | 89         |
| 5        | title 5 | 18         | 12         |
+----------+---------+------------+------------+

I've tried this

SELECT s.id,
       s .title,
       Count(v.id) AS upvote
FROM   story s
       INNER JOIN vote mp
               ON v.story_id = s.id
                  AND v.type = 1
WHERE  (SELECT Count(id) up
        FROM   vote
        WHERE  type = 1
               AND story_id = s.id) - (SELECT Count(id) down
                                       FROM   vote
                                       WHERE  type = 0
                                              AND story_id = s.id) > 0
GROUP  BY s.id;  

But I don't get the difference in the results. Only the number of upvotes:

+----------+---------+------------+
| story_id | title   | nb_upvotes |
+----------+---------+------------+
| 1        | title 1 | 45         |
| 4        | title 4 | 89         |
| 5        | title 5 | 12         |
+----------+---------+------------+

How could I achieve this ?

Thanks

EDIT:

Thanks to @miken32 I got it to work with this

SELECT id, title,
    (SELECT COUNT(id) FROM story_moderation WHERE story_id = s.id AND type = 1) AS upvotes,
    (SELECT COUNT(id) FROM story_moderation WHERE story_id = s.id AND type = 0) AS downvotes,
    (SELECT COUNT(id) FROM story_moderation WHERE story_id = s.id AND type = 1) - (SELECT COUNT(id) FROM story_moderation WHERE story_id = s.id AND type = 0) as diff
FROM story s
HAVING upvotes - downvotes > 0

But this is a lot of subqueries, isn't it too resource consuming?

Hard to say without anything to test on, but does this do the trick? If you want to capture any info in the result set, it has to be specified in your SELECT clause.

SELECT id, title,
    (SELECT COUNT(id) FROM vote WHERE story_id = s.id AND type = 1) AS upvotes,
    (SELECT COUNT(id) FROM vote WHERE story_id = s.id AND type = 0) AS downvotes
FROM story s
HAVING upvotes - downvotes NOT IN (-1, 0, 1);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM