【问题标题】:Mysql query - Count items grouping by year and including "sub-counts"Mysql 查询 - 按年份分组计数项目,包括“子计数”
【发布时间】:2012-05-11 09:34:52
【问题描述】:

我有一个像这样的“事件”表

   id   |  user_id   |   date     |  is_important
---------------------------------------------------
   1    |     3      | 01/02/2012 |       0
   1    |     3      | 01/02/2012 |       1
   1    |     3      | 01/02/2011 |       1
   1    |     3      | 01/02/2011 |       1
   1    |     3      | 01/02/2011 |       0

基本上,我需要得到的是:

(for the user_id=3)

   year   |  count   |   count_importants
--------------------------------------------
  2012    |    2     |          1
  2011    |    3     |          2

我试过了:

SELECT YEAR(e1.date) as year,COUNT(e1.id) as count_total, aux.count_importants
FROM events e1 
LEFT JOIN 
(
  SELECT YEAR(e2.date) as year2,COUNT(e2.id) as count_importants
  FROM `events` e2
  WHERE e2.user_id=18 
  AND e2.is_important = 1
  GROUP BY year2
) AS aux ON aux.year2 = e1.year
WHERE e1.user_id=18 
GROUP BY year

但是mysql给我一个错误

#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'aux ON aux.year2 = e1.year WHERE e1.user_id=18 GROUP BY year LIMIT 0, 30' at line 10

而且我已经没有办法进行这个查询 u_Uº。是否可以只使用一个查询来做到这一点??

提前致谢

【问题讨论】:

    标签: mysql count subquery aggregate


    【解决方案1】:

    编辑:我认为我把事情复杂化了。你不能在一个简单的查询中做到这一点吗?

    SELECT 
        YEAR(`year`) AS `year`, 
        COUNT(`id`) AS `count`, 
        SUM(`is_important`) AS `count_importants`
    FROM `events`
    WHERE user_id = 18
    GROUP BY YEAR(`year`)
    

    这是添加摘要的大解决方案 :)

    考虑使用MySQL GROUP BY ROLLUP。这基本上与普通的 GROUP BY 完成类似的工作,但也会为摘要添加行。

    在下面的示例中,您会看到 2000 年芬兰的两条记录,分别是 1500 英镑和 100 英镑,然后是 NULL 产品的总价值为 1600 英镑的行。它还为按分组的每个维度添加 NULL 汇总行。

    来自手册:

    SELECT year, country, product, SUM(profit)
    FROM sales
    GROUP BY year, country, product WITH ROLLUP
    
    +------+---------+------------+-------------+
    | year | country | product    | SUM(profit) |
    +------+---------+------------+-------------+
    | 2000 | Finland | Computer   |        1500 |
    | 2000 | Finland | Phone      |         100 |
    | 2000 | Finland | NULL       |        1600 |
    | 2000 | India   | Calculator |         150 |
    | 2000 | India   | Computer   |        1200 |
    | 2000 | India   | NULL       |        1350 |
    | 2000 | USA     | Calculator |          75 |
    | 2000 | USA     | Computer   |        1500 |
    | 2000 | USA     | NULL       |        1575 |
    | 2000 | NULL    | NULL       |        4525 |
    | 2001 | Finland | Phone      |          10 |
    | 2001 | Finland | NULL       |          10 |
    | 2001 | USA     | Calculator |          50 |
    | 2001 | USA     | Computer   |        2700 |
    | 2001 | USA     | TV         |         250 |
    | 2001 | USA     | NULL       |        3000 |
    | 2001 | NULL    | NULL       |        3010 |
    | NULL | NULL    | NULL       |        7535 |
    +------+---------+------------+-------------+
    

    这是一个与您的情况特别匹配的示例:

    SELECT year(`date`) AS `year`, COUNT(`id`) AS `count`, SUM(`is_important`) AS `count_importants`
    FROM new_table
    GROUP BY year(`date`) WITH ROLLUP;
    

    【讨论】:

    • 大声笑...我讨厌最复杂的解决方案。您的解决方案在这种情况下可以工作,因为“is_important”是一个布尔值:P 谢谢!!
    • 确实如此。我经常使用这样的 SUM 解决方案,即使事情不是布尔值,通过使用 CASE 以某种方式将字符串转换为数字。基本上是旋转。 SUM(CASE WHEN engineer = 'Fred' THEN 1 ELSE 0 END) AS FredTotal
    【解决方案2】:

    别名 year - year(e1.date) AS year 在 JOIN ON 子句中不可见。尝试使用这个条件 -

    ...
    LEFT JOIN
    (
    ...
    ) ON aux.year2 = year(e1.date) -- e1.year --> year(e1.date)
    ...
    

    【讨论】:

    • hmm noup.. 我试过) AS aux ON aux.year2 = YEAR(e1.date) 什么都没有 u_u
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-20
    • 1970-01-01
    • 2018-07-11
    • 2019-02-16
    相关资源
    最近更新 更多