如何加入多个计数(*)查询?

时间:2014-02-13 07:04:30

标签: mysql join count query-optimization

有没有办法将多个计数(*)查询连接到一个?我知道我不需要两次准备最后两个查询,但这不是问题所在。我不知道如何以正确的方式做到这一点。

$sth = $this->_db->prepare('SELECT count(*) FROM posts WHERE topicid = ?');
$sth->execute( array( $this->_id ) );
$numPosts = $sth->fetch(\PDO::FETCH_ASSOC);

$sth = $this->_db->prepare('SELECT count(*) FROM topic_activity WHERE topicid = ?');
$sth->execute( array( $this->_id ) );
$numViews = $sth->fetch(\PDO::FETCH_ASSOC);

$sth = $this->_db->prepare('SELECT count(*) FROM topic_activity WHERE topicid = ? AND likes = 1');
$sth->execute( array( $this->_id ) );
$numLikes = $sth->fetch(\PDO::FETCH_ASSOC);

$sth = $this->_db->prepare('SELECT count(*) FROM topic_activity WHERE topicid = ? AND likes = -1');
$sth->execute( array( $this->_id ) );
$numDislikes = $sth->fetch(\PDO::FETCH_ASSOC);

2 个答案:

答案 0 :(得分:2)

SELECT count_post, topic_activity
FROM(
    SELECT count(*) AS count_post, NULL AS topic_activity FROM posts WHERE topicid = ?
UNION
    SELECT NULL AS count_post, count(*) AS topic_activity FROM topic_activity WHERE topicic =?
) T
GROUP by count_post, topic_activity

让我知道它是否有效

答案 1 :(得分:1)

虽然user3106988的答案“有效”,但我会采用更“垂直”的方法(并将id存储在一个变量中,所以你只需要传递一次,这可能不适用于你的环境,所以你可能需要用4个问号替换@ id's,但希望不是):

SET @id = ?;

SELECT info = 'Posts', count(*) FROM posts WHERE topicid = @id
UNION ALL
SELECT info = 'Views', count(*) FROM topic_activity WHERE topicid = @id
UNION ALL
SELECT info = 'Likes', count(*) FROM topic_activity WHERE topicid = @id AND likes = 1
UNION ALL
SELECT info = 'DisLikes', count(*) FROM topic_activity WHERE topicid = @id AND likes = -1

但是返回4条记录,然后您需要通过info字段提取数据。所以,建立在user3106988的答案的基础上,只返回1条记录,其中包含不同领域的所有信息,你可以真正去找喜欢的&尽可能少的努力。应该很快。

SET @id = ?;

SELECT SUM(count_posts) as count_posts, 
       SUM(views) as views, 
       SUM(likes) as likes, 
       SUM(dislikes) as dislikes
FROM(
    SELECT COUNT(*) as count_posts, 
           0 as views, 
           0 as likes, 
           0 as dislikes 
      FROM posts 
     WHERE topicid = @id
UNION ALL
    SELECT 0 as count_posts, 
           COUNT(*) as views, 
           SUM(Case WHEN likes = 1 THEN 1 ELSE 0 END) as likes, 
           SUM(Case WHEN likes = -1 THEN 1 ELSE 0 END) as dislikes 
      FROM topic_activity 
     WHERE topicid = @id
) T;