当GROUP BY不产生匹配时,返回计数为0的行

时间:2017-08-03 21:33:01

标签: mysql sql database

尝试在MySQL中编写一个查询,该查询在特定时间范围内执行由特定deviceToken执行的4个不同操作,并返回actiondeviceToken和{{1该行动被采取了多少次。我的问题是,为了正确处理结果,我总是需要所有4个动作成为返回的一部分,即使计数为0,并且count众所周知也不能与之一起发挥作用。这是我目前的查询:

GROUP BY

对于在该时间范围内执行了所有4项操作的SELECT `action`, deviceToken, CASE WHEN `action` = 'calendar' THEN COUNT(*) END AS CalCount, CASE WHEN `action` = 'closinginfo' THEN COUNT(*) END AS CloseingCount, CASE WHEN `action` = 'generalinfo' THEN COUNT(*) END AS GenInfoCount, CASE WHEN `action` = 'login' THEN COUNT(*) END AS LoginCount FROM `action` WHERE deviceToken = '44262f82-3767-49c8-8786-ee377ea00a64' AND (`action` = 'login' OR `action` = 'calendar' OR `action` = 'closinginfo' OR `action` = 'generalinfo') AND `timestamp` > CONCAT(DATE(NOW()),' 23:59:59') - INTERVAL DAYOFWEEK(NOW())+14 DAY AND `timestamp` < CONCAT(DATE(NOW()),' 23:59:59') - INTERVAL DAYOFWEEK(NOW())+7 DAY GROUP BY `action` ,结果如下所示:

enter image description here

我的客户处理这个结果的方式已经很完美了。但是,花费少于全部4个动作的deviceToken如下所示:

enter image description here

我需要让我的数据处理普遍适用的是那些丢失的行仍然返回,但只是将这些计数列为0.有没有人知道如何实现这一点?

2 个答案:

答案 0 :(得分:1)

在mysql中,布尔表达式解析为1或0,因此你可以SUM

SELECT  
       SUM(`action` = 'calendar') AS CalCount,
       SUM(`action` = 'closinginfo') AS CloseingCount,
       SUM(`action` = 'generalinfo') AS GenInfoCount,
       SUM(`action` = 'login') AS LoginCount   
FROM `action`
WHERE deviceToken = '44262f82-3767-49c8-8786-ee377ea00a64'
    AND (`action` = 'login' OR `action` = 'calendar' OR `action` = 'closinginfo' OR `action` = 'generalinfo')
    AND `timestamp` > CONCAT(DATE(NOW()),' 23:59:59') - INTERVAL DAYOFWEEK(NOW())+14 DAY
    AND `timestamp` < CONCAT(DATE(NOW()),' 23:59:59') - INTERVAL DAYOFWEEK(NOW())+7 DAY

请注意,此查询未使用GROUP BY,且只有汇总位于SELECT

答案 1 :(得分:0)

使用LEFT JOIN表,其中列出了为这些行获取空值的所有操作。

SELECT t1.`action`, 
       '44262f82-3767-49c8-8786-ee377ea00a64' AS deviceToken, 
       CASE WHEN t1.`action` = 'calendar' THEN COUNT(a.action) END AS CalCount,
       CASE WHEN t1.`action` = 'closinginfo' THEN COUNT(a.action) END AS CloseingCount,
       CASE WHEN t1.`action` = 'generalinfo' THEN COUNT(a.action) END AS GenInfoCount,
       CASE WHEN t1.`action` = 'login' THEN COUNT(a.action) END AS LoginCount
FROM (SELECT 'calendar' AS action
      UNION ALL
      SELECT 'closinginfo'
      UNION ALL 
      SELECT 'generalinfo'
      UNION ALL
      SELECT 'login') AS t1
LEFT JOIN `action` AS a
ON a.action = t1.action
    AND deviceToken = '44262f82-3767-49c8-8786-ee377ea00a64'
    AND `timestamp` > CONCAT(DATE(NOW()),' 23:59:59') - INTERVAL DAYOFWEEK(NOW())+14 DAY
    AND `timestamp` < CONCAT(DATE(NOW()),' 23:59:59') - INTERVAL DAYOFWEEK(NOW())+7 DAY
GROUP BY t1.`action`