我有基于出生和性别的CASE条件的SQL语法。以下是我使用的示例查询
SELECT Age, SUM(gender = 'M') M, SUM(gender = 'F') F, COUNT(*) TotalPerson FROM (SELECT CASE WHEN FLOOR(DATEDIFF(CURDATE(), birdth) / 365) 60 THEN '60 Above' END Age, gender FROM society) ageList GROUP BY Age
结果变成这样:
Age | M | F | TotalPerson -------------------------------- 19 - 25 | 1 | 0 | 1 19 - 25 | 1 | 0 | 1 26 - 45 | 1 | 2 | 3 46 - 60 | 0 | 1 | 1 60 Above | 0 | 2 | 2
这里的完整语法是我的sqlfiddle: http://sqlfiddle.com/#!9/e8c12a/2
但我真正需要的结果是显示空值的年龄。 像这样的例子:
Age | M | F | TotalPerson -------------------------------- 0 - 5 | 0 | 0 | 0 6 - 10 | 0 | 0 | 0 11 - 18 | 0 | 0 | 0 19 - 25 | 1 | 0 | 1 19 - 25 | 1 | 0 | 1 26 - 45 | 1 | 2 | 3 46 - 60 | 0 | 1 | 1 60 Above | 0 | 2 | 2
答案 0 :(得分:2)
你可以加入社会年龄:
SELECT
Age,
COALESCE(SUM(gender = 'M'), 0) M,
COALESCE(SUM(gender = 'F'), 0) F,
COALESCE(SUM(gender = 'M'), 0) + COALESCE(SUM(gender = 'F'), 0) TotalPerson
FROM
(
SELECT '0 - 5' AS Age, 0 AS age1, 6 AS age2 UNION
SELECT '6 - 10', 6, 10 UNION
SELECT '11 - 18', 11, 18 UNION
SELECT '19 - 25', 19, 25 UNION
SELECT '26 - 45', 26, 45 UNION
SELECT '46 - 60', 46, 60 UNION
SELECT '60 Above', 60, 1000
) ages
LEFT JOIN society ON FLOOR(DATEDIFF(CURDATE(), birdth) / 365) BETWEEN age1 AND age2
GROUP BY Age
ORDER BY age1
上的示例
答案 1 :(得分:1)
这里有几点需要考虑。
首先,如果必须使用SQL,您应该认真考虑。 Imho,查询应该只负责从数据库中获取数据,而不是 - 如果你这样做 - 在GUI或类似的东西中显示所有年龄组都是完整的。
其次,您的方法无效的原因在于查询的处理方式。用我自己的话说,MySQL的作用是:
第三次,最后但并非最不重要。如果你真的必须在MySQL中这样做,这将是一个可行的方法。创建一个包含您想要拥有的所有年龄组的表(也可以是临时表),然后以正确的方式加入(在我的示例中使用RIGHT联接,但我认为还可以转换查询并执行LEFT join,你不能使用INNER JOIN,因为这会否定最终结果集中的行在连接的一侧是NULL的可能性,所以你也得到你的NULL结果。 我根据您的方法创建了一个简单的example on sqlfiddle。 但请注意,这只是一个快速而肮脏的解决方案(例如,我通过将age_to设置为1000来在最大日期范围内作弊)。
在旁注:我建议不要通过将天数除以365来计算年龄。请记住,有闰年,所以随着时间的推移,您的结果将变得越来越不准确。最简单(也是最可靠的方法)就是从当前年份减去出生年份并检查今年是否已经过去了,以便从结果中减去1,如果没有的话。