返回准备好的陈述中的总计数

时间:2014-05-11 17:00:31

标签: php mysql sql count

以下语句从用户位于特定帐户的特定计算机中的各种表/条件中获取user_ids的行计数。它按预期工作。示例输出将是这样的:

Array
(
    [0] => Array
        (
            [computer_name] => COMPUTER_1
            [username] => Steve
            [t1count] => 13
            [t2count] => 
            [t3count] => 23
            [t4count] => 64
        )
    ... and so on for each
声明:

$stmt = $db->prepare("
    SELECT c.computer_name, users.username, t1count, t2count, t3count, t4count 
    FROM
        ( SELECT account_id, computer_id, computer_name
            FROM computers
            WHERE account_id = ".$_SESSION['user']['account_id']."
            ORDER BY computer_id ASC LIMIT 0, ".$_SESSION['user']['licenses']."
        ) as c
        LEFT JOIN users
            on users.computer_id = c.computer_id

        LEFT JOIN
            (SELECT user_id, COUNT(user_id) as t1count
            FROM t1
            WHERE t1.title LIKE 'started'
            GROUP BY user_id) as t_t1
                on t_t1.user_id = users.user_id

        LEFT JOIN
            (SELECT user_id, COUNT(user_id) as t2count
            FROM t2
            GROUP BY user_id) as t_t2
                on t_t2.user_id = users.user_id

        LEFT JOIN
            (SELECT user_id, COUNT(user_id) as t3count
            FROM t1
            WHERE t1.title LIKE 'blocked'
            GROUP BY user_id) as t_t3
                on t_t3.user_id = users.user_id     

        LEFT JOIN
            (SELECT user_id, COUNT(user_id) as t4count
            FROM t1
            WHERE t1.title LIKE 'closed'
            GROUP BY user_id) as t_t4
                on t_t4.user_id = users.user_id

            ... and so on for each

    WHERE c.account_id = ?
");

我也希望在此语句中返回totalsum = t1count + t2count + t3count + t4count,但似乎无法正常工作。在这种情况下,我无法进行外部处理(添加返回的值)......它需要在语句中。如果有更好的选择,我也对我已有的任何建议持开放态度。

1 个答案:

答案 0 :(得分:1)

你想用这些价值做什么? SUM(t1count,t2count,t3count,t4count) AS totalsum应该可以计算数量。

您的查询有点难以阅读。你有隐式和明确的JOIN。当你通常可以一次性完成所有操作时,你会进行多次分组并拉动列。如果你共享一个SQLFiddle,我将能够清理它,但简而言之:

SELECT 
    c.computer_name, 
    users.username, 
    count(t_t1.user_id) AS t1count, 
    count(t_t2.user_id) AS t2count, 
    count(t_t3.user_id) AS t3count, 
    count(t_t4.user_id) AS t4count, 
    (count(t_t1.user_id)+count(t_t2.user_id)+count(t_t3.user_id)+count(t_t4.user_id)) AS totalsum FROM users
LEFT JOIN computers AS c ON users.computer_id=c.computer_id AND c.account_id=?
LEFT JOIN t1 AS t_t1 ON t_t1.user_id = users.user_id AND t_t1.title LIKE "started"
LEFT JOIN t2 AS t_t2 ON t_t2.user_id = users.user_id
LEFT JOIN t1 AS t_t3 ON t_t3.user_id = users.user_id AND t_t3.title LIKE 'blocked'
LEFT JOIN t1 AS t_t4 ON t_t4.user_id = users.user_id AND t_t4.title LIKE 'closed'
WHERE c.account_id = ?
AND t_t1.title LIKE started
GROUP BY users.user_id;

正如我所说,这可能需要调整,但它更清晰,更容易阅读,并且应该完成非常相似的事情。

或者,如果在将其更改为完全显式联接而不是使用SUM时无法使查询以您希望的方式运行,请尝试将值一起添加,就像我在示例中一样以上。它应该阻止它们以相同的方式聚合。

修改

在查看了您的SQLFiddle之后,我已经修改了一个解决方案,它取消了嵌套查询。积极的是它更清洁。否定的是,它要求您使用IN子句指定用户。

SELECT computers.account_id,computers.computer_id,computers.computer_name,users.user_id,users.username,count(distinct t_count1.log_id) AS count1,count(distinct t_count2.log_id) AS count2,count(distinct t_count3.log_id) AS count3, count(distinct t_count4.event_id) AS count4,
(count(distinct t_count1.log_id) + count(distinct t_count2.log_id) + count(distinct t_count3.log_id) + count(distinct t_count4.event_id)) AS totalcount

FROM users
INNER JOIN computers ON computers.computer_id=users.computer_id
LEFT JOIN logs AS t_count1 ON t_count1.type LIKE 'type1' AND t_count1.user_id=users.user_id
LEFT JOIN logs AS t_count2 ON t_count2.type LIKE 'type2' AND t_count2.user_id=users.user_id
LEFT JOIN logs AS t_count3 ON t_count3.type LIKE 'type3' AND t_count3.user_id=users.user_id
LEFT JOIN events AS t_count4 ON t_count4.user_id = users.user_id
WHERE computers.account_id=1 AND computers.computer_id in (1,2)
GROUP BY users.user_id
ORDER BY users.user_id ASC,computers.computer_id ASC;

如果您因任何原因选择保留当前的查询结构,那么适应它应该会让它适合您:

select *,ifnull(count1,0)+ifnull(count2,0)+ifnull(count3,0)+ifnull(count4,0) AS totalcount from
  ( select account_id, computer_id, computer_name
     from computers
     order by computer_id asc limit 0, 2
  ) as c

  left join users
    on users.computer_id = c.computer_id

  left join
    (select user_id, count(user_id) as count1
       from logs
       where logs.type like 'type1'
       group by user_id) as t_count1
    on t_count1.user_id = users.user_id

  left join
    (select user_id, ifnull(count(user_id),0) as count2
       from logs
       where logs.type like 'type2'
       group by user_id) as t_count2
    on t_count2.user_id = users.user_id

  left join
    (select user_id, count(user_id) as count3
       from logs
       where logs.type like 'type3'
       group by user_id) as t_count3
    on t_count3.user_id = users.user_id

  left join
    (select user_id, count(user_id) as count4
       from events
       group by user_id) as t_count4
      on t_count4.user_id = users.user_id

   where c.account_id = 1;

我的建议是按照每个查询来理解你要求SQL做什么。要将所有值实际添加到一起,您应该计算返回的记录数。计算主键值可帮助您计算记录。另外,使用您的另一个示例,第二个示例中的ifnull确保 null 值不会干扰添加。 “如果值为null,则将其改为0。”