当CASE不存在时,返回0表示SQL计数

时间:2016-01-25 18:17:37

标签: mysql sql stored-procedures

我有两个表Log和Player。 Log使用playerId和日期存储每个游戏的日志。播放器表格中的玩家信息为年龄和性别等。我正在编写一个带有两个日期的SQL存储过程,并将根据两个日期之间的年龄范围和性别来计算LogId和组。但是当我运行SQL程序时,如果在该时间段内没有玩家存在,则它不会显示所有Age_Range / Gender条目。我试图获取所有Age_Range / Gender条目及其实际计数或计数= 0,如果他们不存在。 我甚至尝试过改变

count(L.LogId) as Count, 

count(IFNULL(L.LogId, 0)) as Count,

我的SQL程序是:

CREATE PROCEDURE `SHOW_AGE_RANGE` (IN date1 CHAR(10), IN date2 CHAR(10))
 BEGIN
 SELECT
  count(L.LogId) as Count,
  CASE
     WHEN P.age BETWEEN 13 AND 18 THEN '13-18'
     WHEN P.age BETWEEN 19 AND 25 THEN '19-25'
     WHEN P.age BETWEEN 26 AND 39 THEN '26-39'
     WHEN P.age BETWEEN 40 AND 59 THEN '40-59'
     WHEN P.age > 59 THEN '60+' 
 END as Age_Range,
 CASE
    WHEN P.gender  = 0 then 'Female'
    WHEN P.gender  = 1 then 'Male'
 END  as Gender    
 FROM Log L
 LEFT JOIN Player P ON L.playerId = P.playerId 

 WHERE CAST(L.createdDate AS DATE) BETWEEN CAST(date1 AS DATE) AND CAST(date2 AS DATE)  
 GROUP BY Age_Range, Gender;    
END

SQL过程的输出:

Count  Age_Range  Gender 
----------------------------------
'1'    '13-18'    'Male'
'1'    '19-25'    'Female'
'3'    '26-39'    'Female'
'2'    '40-59'    'Male'
'1'    '60+'      'Female'

预期输出

Count  Age_Range  Gender 
----------------------------------
'0'    '13-18'    'Female'
'1'    '13-18'    'Male'
'1'    '19-25'    'Female'
'0'    '19-25'    'Male'
'3'    '26-39'    'Female'
'0'    '26-39'    'Male'
'0'    '40-59'    'Female'
'2'    '40-59'    'Male'
'1'    '60+'      'Female'
'0'    '60+'      'Male'

2 个答案:

答案 0 :(得分:2)

您需要从年龄范围和性别开始。真的,你要查询那些,玩家数据只是你要添加的东西。由于您还没有表中的年龄范围(您应该考虑添加它),因此您需要为子查询创建一个虚拟表。

SELECT
    COUNT(L.playerId) AS cnt,
    AG.age_range,
    G.gender
FROM
(
    SELECT 13 AS min_age, 18 AS max_age, '13-18' AS age_range
    UNION ALL
    SELECT 19 AS min_age, 25 AS max_age, '19-' AS age_range
    UNION ALL
    SELECT 26 AS min_age, 39 AS max_age, '26-39' AS age_range
    UNION ALL
    SELECT 40 AS min_age, 59 AS max_age, '40-59' AS age_range
    UNION ALL
    SELECT 60 AS min_age, 999 AS max_age, '60+' AS age_range
) AS AG
CROSS JOIN
(
    SELECT 0 AS gender_value, 'Female' AS gender
    UNION ALL
    SELECT 1 AS gender_value, 'Male' AS gender
) AS G
LEFT JOIN Player P ON
    P.age BETWEEN AG.min_age AND AG.max_age AND
    P.gender = G.gender_value
LEFT OUTER JOIN Log L ON
    L.playerId = P.playerId AND
    CAST(L.createdDate AS DATE) BETWEEN CAST(date1 AS DATE) AND CAST(date2 AS DATE)
GROUP BY
    AG.age_range, G.gender

答案 1 :(得分:0)

看起来您希望外部联接到Log表。交换PlayerLog表,并将createdDate列上的谓词重定位到ON子句。

像这样:

  FROM Player P
  LEFT 
  JOIN Log L
    ON L.playerId = P.playerId 
   AND CAST(L.createdDate AS DATE) BETWEEN CAST(date1 AS DATE) AND CAST(date2 AS DATE)
 GROUP BY Age_Range, Gender;