我做了以下查询,按年龄组选择人数,作为计数和百分比。年龄在我的数据库中存储为0000-00-00
。
SELECT AgeGroup, count(*) AS count, ROUND(sum( 100 ) / total) AS percentage
FROM (
SELECT case
when age between 0 and 17 then '00 - 17'
when age between 18 and 24 then '18 − 24'
when age between 25 and 34 then '25 − 34'
when age between 35 and 44 then '35 − 44'
when age between 45 and 54 then '45 − 54'
when age between 55 and 64 then '55 − 64'
when age between 65 and 125 then '65+'
else 'Unknown'
end AS AgeGroup
FROM (
SELECT ROUND(DATEDIFF(Cast(NOW() as Date),
Cast(dateofbirth as Date)) / 365, 0) as age
FROM people
) as SubQueryAlias
) as SubQueryAlias2
CROSS JOIN (SELECT count( * ) AS total FROM people)x
group by
AgeGroup
目前的结果是:
AgeGroup | count | percentage
00 - 17 33 1
18 − 24 235 5
.. .. ..
我需要的是添加查询以分隔男性/女性/未知结果:
AgeGroup | gender | count | percentage
00 - 17 M 33 1
00 - 17 F 33 1
.. .. .. ..
答案 0 :(得分:1)
我真的希望我错了......但不断出错的原因是......你没有选择性别?
另外,一个书呆子的旁注,365天不能一年,它大约365.25天XD这意味着你的等式稍微偏离哈哈
SELECT AgeGroup, gender, count(*) AS count, ROUND(sum( 100 ) / total) AS percentage
FROM (
SELECT case
when age between 0 and 17 then '00 - 17'
when age between 18 and 24 then '18 − 24'
when age between 25 and 34 then '25 − 34'
when age between 35 and 44 then '35 − 44'
when age between 45 and 54 then '45 − 54'
when age between 55 and 64 then '55 − 64'
when age between 65 and 125 then '65+'
else 'Unknown'
end AS AgeGroup, gender
FROM (
SELECT ROUND(DATEDIFF(Cast(NOW() as Date),
Cast(dateofbirth as Date)) / 365, 0) as age,
gender
FROM people
) as SubQueryAlias
) as SubQueryAlias2
CROSS JOIN (SELECT count( * ) AS total FROM people)x
group by
AgeGroup, gender
答案 1 :(得分:1)
您可以通过定义范围表来获得最简单的时间。这也可以防止您需要对每个条目进行日期数学运算,因此可能更有效地进行分组。
首先,年龄范围表:
SELECT '00 - 17' AS ageGroup, CURRENT_DATE AS lower, CURRENT_DATE - INTERVAL 18 YEAR AS upper
UNION ALL
SELECT '18 - 24', CURRENT_DATE - INTERVAL 18 YEAR, CURRENT_DATE - INTERVAL 25 YEAR
UNION ALL
SELECT '25 - 34', CURRENT_DATE - INTERVAL 25 YEAR, CURRENT_DATE - INTERVAL 35 YEAR
UNION ALL
SELECT '35 - 44', CURRENT_DATE - INTERVAL 35 YEAR, CURRENT_DATE - INTERVAL 45 YEAR
UNION ALL
SELECT '45 - 54', CURRENT_DATE - INTERVAL 45 YEAR, CURRENT_DATE - INTERVAL 55 YEAR
UNION ALL
SELECT '55 - 64', CURRENT_DATE - INTERVAL 55 YEAR, CURRENT_DATE - INTERVAL 65 YEAR
UNION ALL
SELECT '65+', CURRENT_DATE - INTERVAL 65 YEAR, null
UNION ALL
SELECT 'Unknown', null, null
...它会生成一个关于你期望的表格。请注意,上限是独占的,这就是它使用与下一行的下限相同的值的原因。另请注意:1)'65+'
括号没有上限,2)'Unknown'
括号没有上限。
当然,我们还需要一个Gender
表:
SELECT 'M' AS gender
UNION ALL
SELECT 'F'
UNION ALL
SELECT 'Unknown'
(作为旁注,我通常使用多行VALUES(...)
语句,但是由于某种原因,SQL Fiddle似乎不喜欢MySQL子查询中的语法。请使用您认为合适的语句。 )
我们需要最后一项知识:
具体而言,COUNT(<expression>)
将忽略null
行。因此,我们可以将完整查询拼接在一起,类似于:
SELECT AgeRange.ageGroup, Gender.gender,
COUNT(People.id), ROUND(100 * COUNT(People.id) / Total.countOfPeople) AS percentage
FROM (SELECT '00 - 17' AS ageGroup, CURRENT_DATE AS lower, CURRENT_DATE - INTERVAL 18 YEAR AS upper
UNION ALL
SELECT '18 - 24', CURRENT_DATE - INTERVAL 18 YEAR, CURRENT_DATE - INTERVAL 25 YEAR
UNION ALL
SELECT '25 - 34', CURRENT_DATE - INTERVAL 25 YEAR, CURRENT_DATE - INTERVAL 35 YEAR
UNION ALL
SELECT '35 - 44', CURRENT_DATE - INTERVAL 35 YEAR, CURRENT_DATE - INTERVAL 45 YEAR
UNION ALL
SELECT '45 - 54', CURRENT_DATE - INTERVAL 45 YEAR, CURRENT_DATE - INTERVAL 55 YEAR
UNION ALL
SELECT '55 - 64', CURRENT_DATE - INTERVAL 55 YEAR, CURRENT_DATE - INTERVAL 65 YEAR
UNION ALL
SELECT '65+', CURRENT_DATE - INTERVAL 65 YEAR, null
UNION ALL
SELECT 'Unknown', null, null) AgeRange
CROSS JOIN (SELECT 'M' AS Gender
UNION ALL
SELECT 'F'
UNION ALL
SELECT 'Unknown') Gender
CROSS JOIN (SELECT COUNT(*) countOfPeople
FROM People) Total
LEFT JOIN People
ON ((People.dateOfBirth > AgeRange.upper AND dateOfBirth <= AgeRange.lower)
OR (People.dateOfBirth <= AgeRange.lower AND AgeRange.upper IS NULL)
OR (AgeRange.lower IS NULL AND AgeRange.upper IS NULL AND People.dateOfBirth IS NULL))
AND (Gender.gender = People.gender
OR Gender.gender = 'Unknown' AND People.gender IS NULL)
GROUP BY AgeRange.ageGroup, Gender.gender
SQL Fiddle Demo
(请注意,小提琴演示使用此帖子的日期'2014-07-21'
作为CURRENT_DATE
,以便为将来的读者提供稳定的年龄范围查询。)