[英]Return 0 for SQL count when CASE does not exist
I have two tables Log and Player. 我有两个表Log和Player。 Where Log stores each game play log with a playerId and date. Log使用playerId和日期存储每个游戏的日志。 and the Player table has the Players info as Age and Gender ..etc. 播放器表格中的玩家信息为年龄和性别等。 I'm writing an SQL stored procedure that takes two dates and will count the LogId and group by age range and gender between the two dates. 我正在编写一个SQL存储过程,该过程需要两个日期,并按两个日期之间的年龄范围和性别计算LogId和组。 but when i run the SQL procedure, it doesn't show all the Age_Range/Gender entries when no player exists in that period.I'm trying to get all Age_Range/Gender entries with the their actual count or count= 0 if they don't exist. 但是当我运行SQL程序时,它没有显示当时没有玩家存在的所有Age_Range / Gender条目。我试图获取所有Age_Range / Gender条目的实际计数或计数= 0如果他们不不存在。 I've even tried changing 我甚至尝试过改变
count(L.LogId) as Count,
To 至
count(IFNULL(L.LogId, 0)) as Count,
My SQL procedure is : 我的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
Output of the SQL Procedure: SQL过程的输出:
Count Age_Range Gender
----------------------------------
'1' '13-18' 'Male'
'1' '19-25' 'Female'
'3' '26-39' 'Female'
'2' '40-59' 'Male'
'1' '60+' 'Female'
The Expected Output 预期产出
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'
You need to start out with your age ranges and genders. 你需要从你的年龄范围和性别开始。 Really, you're querying off of those and the player data is just something that you're adding to them. 真的,你要查询那些,玩家数据只是你要添加的东西。 Since you don't already have the age ranges in a table (you should probably consider adding that) then you'll need to create a virtual table for those as a subquery. 由于您还没有表中的年龄范围(您应该考虑添加它),因此您需要为子查询创建一个虚拟表。
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
It looks like you want the outer join to the Log
table. 看起来您希望外部联接到Log
表。 Swap the Player
and Log
tables, and relocate the predicate on the createdDate
column to the ON
clause. 交换Player
和Log
表,并将createdDate
列上的谓词重createdDate
到ON
子句。
Like this: 像这样:
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;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.