【问题标题】:How can I get multiple COUNT's in a single SQL query with multiple WHERE conditions?如何在具有多个 WHERE 条件的单个 SQL 查询中获取多个 COUNT?
【发布时间】:2019-03-05 22:05:07
【问题描述】:

我需要获取有关用户在网络应用上的活动的报告。

首先,我有一个表格,用于计算用户登录我们应用的次数,如下所示:

user_activity
-----------------------------------------------------
| ID_login | Username | Date       | Hour     | ... |
|---------------------|------------|----------|-----|
|        1 | john     | 2019-03-01 | 08:49:24 | ... |
|        2 | john     | 2019-03-01 | 14:12:49 | ... |
|        3 | jane     | 2019-03-03 | 10:02:31 | ... |
|      ... | ...      | ...        | ...      | ... |
-----------------------------------------------------

我想要做的是有一份报告,它不仅可以为我提供设定时间段内每个用户的登录总量。我已经可以做到了。当我尝试获取前一年每个月的报告时,我遇到了困难,其中月份位于不同的列中。

我希望我的查询生成的表如下所示:

user_activity
--------------------------------------------------------
| Username | login_total | login_jan | login_feb | ... |
|------------------------|-----------|-----------|-----|
| john     |        4827 |       164 |       191 | ... |
| james    |        3866 |        92 |       144 | ... |
| jane     |        2979 |       104 |        92 | ... |
| ...      |         ... |       ... |       ... | ... |
--------------------------------------------------------

如您所见,我正在考虑将 login_total 值用于 ORDER BY。

这就是我目前所拥有的。

SELECT
    user_activity.Username,
    COUNT(user_activity.ID_login) AS login_total

FROM
    user_activity

WHERE
    user_activity.Date >= '2018-01-01'
    AND
    user_activity.Date <= '2018-12-31'

如何使用 COUNT 获取另一列,但条件不同?我应该把这些标准放在哪里?我尝试过使用 IF 语句和 HAVING 语句,但没有成功。

我在想这样的事情......?

SELECT
    user_activity.Username,
    COUNT(
        IF
            (user_activity.Date >= '2019-01-01'
            AND
            user_activity.Date <= '2019-01-31')
        user_activity.ID_login) 
        AS login_jan,

    COUNT(
        IF
            (user_activity.Date >= '2019-02-01'
            AND
            user_activity.Date <= '2019-02-28')
        user_activity.ID_login) 
        AS login_feb,
    ...

FROM
    user_activity

似乎也没有工作......我错过了什么吗?

【问题讨论】:

    标签: mysql if-statement count heidisql


    【解决方案1】:

    您正在尝试创建一个 PIVOT 表,您可以使用条件聚合在 MySQL 中执行此操作。请注意,您可以使用 MONTHYEAR 函数来简化表达式:

    SELECT u.Username,
           COUNT(*) AS login_total,
           SUM(MONTH(u.Date) = 1) AS login_jan,
           SUM(MONTH(u.Date) = 2) AS login_feb,
           ...
           SUM(MONTH(u.Date) = 12) AS login_dec
    FROM user_activity u
    WHERE YEAR(u.Date) = 2018
    GROUP BY u.Username
    

    这个查询还利用了在数字上下文中 MySQL 将布尔表达式视为 1(真)或 0(假)这一事实,允许我们SUM 这些值。

    【讨论】:

    • 这里也一样。非常感谢您的回答。这是我只有在工作时才能使用的东西,所以我明天早上试试,然后告诉你结果如何。
    • 完美运行。非常感谢!
    【解决方案2】:

    我们可以做条件聚合,像这样:

    SELECT ua.username
         , SUM( ua.date >= '2019-01-01' AND ua.date < '2019-02-01' ) AS login_jan
         , SUM( ua.date >= '2019-02-01' AND ua.date < '2019-03-01' ) AS login_feb
      FROM user_activity ua
     GROUP
        BY ua.username
    

    使用 MySQL 速记,SUM() 聚合中的表达式将被评估为 1、0 或 NULL。我们可以使用 MySQL IF() 函数或更便携的 ANSI SQL CASE 表达式

    SELECT ua.username
         , SUM(IF( ua.date >= '2019-01-01' AND ua.date < '2019-02-01' ,1,0)) AS login_jan
         , SUM(IF( ua.date >= '2019-02-01' AND ua.date < '2019-03-01' ,1,0)) AS login_feb
      FROM user_activity ua
     GROUP
        BY ua.username
    

    SELECT ua.username
         , SUM(CASE WHEN ua.date >= '2019-01-01' AND ua.date < '2019-02-01' THEN 1 ELSE 0 END) AS login_jan
         , SUM(CASE WHEN ua.date >= '2019-02-01' AND ua.date < '2019-03-01' THEN 1 ELSE 0 END) AS login_feb
      FROM user_activity ua
     GROUP
        BY ua.username
    

    【讨论】:

    • 好的,谢谢。明天我回去工作后我会试试,然后告诉你进展如何。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-27
    • 1970-01-01
    • 2017-02-24
    • 2021-07-26
    • 1970-01-01
    • 2013-10-03
    相关资源
    最近更新 更多