以下语句从用户位于特定帐户的特定计算机中的各种表/条件中获取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,但似乎无法正常工作。在这种情况下,我无法进行外部处理(添加返回的值)......它需要在语句中。如果有更好的选择,我也对我已有的任何建议持开放态度。
答案 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。”