mysql - 在一个查询中对一个表中的不同值求和

标签 mysql sql performance

我想创建一些关于我的用户的统计信息。

我想根据他们的年龄间隔对他们进行分组,并根据他们的性别对他们进行总结。所以最后我得到了一个这样的表:

   age | male | female | total
  0-18 |    2 |      1 |     3
 18-25 |    3 |      4 |     7
25-100 |   13 |     25 |    38
 total |   18 |     30 |    48

(顺便说一句。这些是示例间隔)

现在我通过对每一行运行这个查询来做到这一点:

SELECT
    SUM(IF(gender = 'male', 1,0)) AS `male`,
    SUM(IF(gender = 'female', 1,0)) AS `female`,
    COUNT(gender) AS `total`
FROM `users`
WHERE 
    `birthday` 
        BETWEEN 
            DATE_SUB(CURDATE(), INTERVAL 25 YEAR) 
        AND 
            DATE_SUB(CURDATE(), INTERVAL 18 YEAR)

并通过我的 php 脚本对结果求和以创建最后的总计行

我如何组合所有这些查询来提高性能,并可能通过 mysql 创建最后的总计行。

我想使用的间隔是:

0-18
18-25
25-31
31-36
36-41
41-46
46-51
51-56
56-61
61-100

编辑: 这是一个表的转储,其中包含一些示例数据以对其进行测试 http://pastebin.com/ytcuu2ge

SQL Fiddle Schema

最佳答案

SELECT  Age,
        SUM(gender = 'female') Female,
        SUM(gender = 'male') Male,
        COUNT(*) TotalPerson
FROM
        (
            SELECT  CASE 
                        WHEN FLOOR(DATEDIFF(CURDATE(), birthday) / 365) BETWEEN 0 AND 18 THEN '00-18'
                        WHEN FLOOR(DATEDIFF(CURDATE(), birthday) / 365) BETWEEN 19 AND 25 THEN '19-25'
                        WHEN FLOOR(DATEDIFF(CURDATE(), birthday) / 365) BETWEEN 26 AND 31 THEN '26-31'
                        WHEN FLOOR(DATEDIFF(CURDATE(), birthday) / 365) BETWEEN 32 AND 36 THEN '32-36'
                        WHEN FLOOR(DATEDIFF(CURDATE(), birthday) / 365) BETWEEN 37 AND 41 THEN '37-41'
                        WHEN FLOOR(DATEDIFF(CURDATE(), birthday) / 365) BETWEEN 42 AND 46 THEN '42-46'
                        WHEN FLOOR(DATEDIFF(CURDATE(), birthday) / 365) BETWEEN 47 AND 51 THEN '47-51'
                        WHEN FLOOR(DATEDIFF(CURDATE(), birthday) / 365) BETWEEN 52 AND 56 THEN '52-56'
                        WHEN FLOOR(DATEDIFF(CURDATE(), birthday) / 365) BETWEEN 57 AND 61 THEN '57-61'
                        WHEN FLOOR(DATEDIFF(CURDATE(), birthday) / 365) BETWEEN 62 AND 100 THEN '62-100'
                    END Age,
                   Gender
            FROM   users
        ) ageList
GROUP   BY Age

输出

╔════════╦════════╦══════╦═════════════╗
║  AGE   ║ FEMALE ║ MALE ║ TOTALPERSON ║
╠════════╬════════╬══════╬═════════════╣
║ 00-18  ║      0 ║    1 ║           1 ║
║ 19-25  ║      6 ║    5 ║          11 ║
║ 26-31  ║     22 ║    4 ║          26 ║
║ 32-36  ║     39 ║   16 ║          56 ║
║ 37-41  ║     20 ║   11 ║          31 ║
║ 42-46  ║     31 ║    6 ║          38 ║
║ 47-51  ║     18 ║    3 ║          21 ║
║ 52-56  ║     11 ║    6 ║          17 ║
║ 57-61  ║     10 ║    6 ║          16 ║
║ 62-100 ║     12 ║   12 ║          24 ║
╚════════╩════════╩══════╩═════════════╝

使用 WITH ROLLUP 输出

╔════════╦════════╦══════╦═════════════╗
║  AGE   ║ FEMALE ║ MALE ║ TOTALPERSON ║
╠════════╬════════╬══════╬═════════════╣
║ 00-18  ║      0 ║    1 ║           1 ║
║ 19-25  ║      6 ║    5 ║          11 ║
║ 26-31  ║     22 ║    4 ║          26 ║
║ 32-36  ║     39 ║   16 ║          56 ║
║ 37-41  ║     20 ║   11 ║          31 ║
║ 42-46  ║     31 ║    6 ║          38 ║
║ 47-51  ║     18 ║    3 ║          21 ║
║ 52-56  ║     11 ║    6 ║          17 ║
║ 57-61  ║     10 ║    6 ║          16 ║
║ 62-100 ║     12 ║   12 ║          24 ║
║ TOTAL  ║    169 ║   70 ║         241 ║
╚════════╩════════╩══════╩═════════════╝

关于mysql - 在一个查询中对一个表中的不同值求和,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15858896/

相关文章:

mysql - 书籍-文章-图像的数据库架构建议

java - 如何为 ResponseEntity<> 返回 'Integer' 类型并在 api 页面上获取结果?

jquery - 最小化 jQuery 实例与创建更多实例

MySQL 1066 : Not unique table/alias error even though I have defined table alias

java - 在 mysql 表 hibernate 中的枚举列上执行条件查询时出错

sql - 对连接字符串的计算字段求和(拆分 acct #s)

performance - SAS:PROC FREQ 或 PROC REPORT 的单个表标题?

javascript - for..in 和 for 循环之间的区别以及计数器声明

mysql - 仅获取最后连续一年的行

针对不同键的 mySQL 查询