MySQL在select case中显示基于性别和生日的空值

时间:2015-12-19 19:46:11

标签: mysql

我有基于出生和性别的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

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

SQL Fiddle

上的示例

答案 1 :(得分:1)

这里有几点需要考虑。

首先,如果必须使用SQL,您应该认真考虑。 Imho,查询应该只负责从数据库中获取数据,而不是 - 如果你这样做 - 在GUI或类似的东西中显示所有年龄组都是完整的。

其次,您的方法无效的原因在于查询的处理方式。用我自己的话说,MySQL的作用是:

  1. 从子查询中获取社会表中的所有行
  2. 使用子查询结果执行主查询
  3. 第三次,最后但并非最不重要。如果你真的必须在MySQL中这样做,这将是一个可行的方法。创建一个包含您想要拥有的所有年龄组的表(也可以是临时表),然后以正确的方式加入(在我的示例中使用RIGHT联接,但我认为还可以转换查询并执行LEFT join,你不能使用INNER JOIN,因为这会否定最终结果集中的行在连接的一侧是NULL的可能性,所以你也得到你的NULL结果。 我根据您的方法创建了一个简单的example on sqlfiddle。 但请注意,这只是一个快速而肮脏的解决方案(例如,我通过将age_to设置为1000来在最大日期范围内作弊)。

    在旁注:我建议不要通过将天数除以365来计算年龄。请记住,有闰年,所以随着时间的推移,您的结果将变得越来越不准确。最简单(也是最可靠的方法)就是从当前年份减去出生年份并检查今年是否已经过去了,以便从结果中减去1,如果没有的话。