如何在查询中按年龄分组显示空数据?

时间:2019-06-03 15:26:45

标签: php mysql sql

我有两个表,表mspencaker和mspengalaman。我进行查询,根据年龄和性别范围显示用户数。到目前为止,查询运行顺利,但是当我更改查询日期时,查询结果将为空。即使数据为空,如何显示数据库中所有现有数据,或将空数据替换为0。

这是我的桌子

mspencaker
----------------
+ IDPencaker   +  --> ID OF table mspencaker(Primary key)
+ TglLahir     +  --> Date of birth from user
+ JenisKelamin +  --> gender of user
+ RegisterDate +  --> the date of registration user, and i use this field to 
----------------      filter data

mspengalaman
-------------------
+ IDpengalaman    +  --> ID OF table mspengalaman(Primary key)
+ IDPencaker      +  --> FOREIGN KEY of mspencaker
+ StatusPekerjaan +  --> i use this field to filter data
-------------------  

这是我的查询

SELECT COUNT(COALESCE(p.IDPencaker, 0)) as total, 
CASE 
 WHEN TIMESTAMPDIFF(YEAR, p.TglLahir, CURDATE()) <= 14 THEN '0-14'
 WHEN TIMESTAMPDIFF(YEAR, p.TglLahir, CURDATE()) BETWEEN 15 AND 19 THEN '15-19' 
 WHEN TIMESTAMPDIFF(YEAR, p.TglLahir, CURDATE()) BETWEEN 20 AND 29 THEN '20-29' 
 WHEN TIMESTAMPDIFF(YEAR, p.TglLahir, CURDATE()) BETWEEN 30 AND 44 THEN '30-44' 
 WHEN TIMESTAMPDIFF(YEAR, p.TglLahir, CURDATE()) BETWEEN 45 AND 54 THEN '45-54' 
 WHEN TIMESTAMPDIFF(YEAR, p.TglLahir, CURDATE()) >= 55 THEN '55' 
END AS age, 
SUM(COALESCE(p.JenisKelamin = 0, 0)) as laki, 
SUM(COALESCE(p.JenisKelamin = 1, 0) ) as cewe 
   FROM mspencaker p LEFT JOIN mspengalaman g 
   ON g.IDPencaker = p.IDPencaker AND g.StatusPekerjaan = 0 
   WHERE p.RegisterDate BETWEEN '2019-01-01' AND '2019-07-01' 
   GROUP BY age 

查询结果如下:

    age   | laki | cewe   | Total
----------+------+--------+------
    0-14  |  3   |   4    |  7
   15-19  |  2   |   1    |  3
   20-29  |  1   |   3    |  4
   30-44  |  10  |   1    |  11
   45-54  |  4   |   6    |  10
    55    |  2   |   1    |  3

但是如果我将WHERE p.RegisterDate BETWEEN '2019-01-01' AND '2019-07-01'更改为WHERE p.RegisterDate BETWEEN '2019-06-01' AND '2019-07-01',则结果如下:

    age   | laki | cewe   | Total
----------+------+--------+------
   null   | null | null   |  null

我想如果我改变条件,那么所有数据仍会出现,并且被赋予0而不是空值。

1 个答案:

答案 0 :(得分:2)

由于并非所有年龄段都每次出现在您的结果中,因此一种解决方案是创建仅包含年龄段(所有年龄段)的另一结果集,LEFT JOIN将结果集包含实际数据并使用IFNULL()为空字段显示0而不是NULL。

                SELECT t1.age,IFNULL(t2.laki,0) as laki,IFNULL(t2.cewe,0) as cewe,IFNULL(t2.Total, 0) AS Total  FROM
                (
                SELECT '0-14' AS age
                UNION ALL 
                SELECT '15-19' AS age
                UNION ALL
                SELECT '20-29' AS age
                UNION ALL
                SELECT '30-44' AS age 
                UNION ALL
                SELECT '45-54' AS age  
                UNION ALL
                SELECT '55' AS age 
                ) t1 
                LEFT JOIN 
                (
                SELECT COUNT(COALESCE(p.IDPencaker, 0)) as total, 
                CASE 
                WHEN TIMESTAMPDIFF(YEAR, p.TglLahir, CURDATE()) <= 14 THEN '0-14'
                WHEN TIMESTAMPDIFF(YEAR, p.TglLahir, CURDATE()) BETWEEN 15 AND 19 THEN '15-19' 
                WHEN TIMESTAMPDIFF(YEAR, p.TglLahir, CURDATE()) BETWEEN 20 AND 29 THEN '20-29' 
                WHEN TIMESTAMPDIFF(YEAR, p.TglLahir, CURDATE()) BETWEEN 30 AND 44 THEN '30-44' 
                WHEN TIMESTAMPDIFF(YEAR, p.TglLahir, CURDATE()) BETWEEN 45 AND 54 THEN '45-54' 
                WHEN TIMESTAMPDIFF(YEAR, p.TglLahir, CURDATE()) >= 55 THEN '55' 
                END AS age, 
                SUM(COALESCE(p.JenisKelamin = 0, 0)) as laki, 
                SUM(COALESCE(p.JenisKelamin = 1, 0) ) as cewe 
                FROM mspencaker p LEFT JOIN mspengalaman g 
                ON g.IDPencaker = p.IDPencaker AND g.StatusPekerjaan = 0 
                WHERE p.RegisterDate BETWEEN '2019-01-01' AND '2019-07-01' 
                GROUP BY age
                )  t2 
                ON t1.age=t2.age