【问题标题】:SQL - count occurrences in a column by DAYSQL - 按 DAY 计算列中的出现次数
【发布时间】:2013-02-22 05:02:44
【问题描述】:

我有一张如下表:

我想按 DAY 来计算 PageURL 和 GROUP 列中 say "ab" 和 "cd" 的出现次数(即,无论一天出现多少次,都算作 1)。

ID  User  Activity  PageURL  ActDateTime
 1  Me    act1      abcd     2013-01-17 19:09:01.040
 2  Me    act2      cdab     2013-01-17 19:09:06.613
 3  You   act2      xyza     2013-01-30 16:10:50.177
 4  Me    act3      xyab     2013-01-30 10:35:09.037

我想要 2 列...1 用于计数“ab”,1 用于计数“cd”。

在上面的例子中,“ab”有 3 个计数,但我只会算作 2,因为前 2 个发生在同一天(所以算作 1)。

同样,PageURL 列中的“cd”有 2 个计数,但我只想算作 1,因为也发生在同一天。

此外,我想按月份分组,即 Jan-12、Feb-12、March-12、April-12 ...等。

非常感谢一些帮助和建议。谢谢!

这是我到目前为止所做的(但它没有考虑按 DAY 分组)

SELECT USER,
       department,
       activity,
       [MonthYear] = DATENAME(mm, ActDateTime)+ ' - ' + 
                                  DATENAME(yy, actdatetime), 
       [ab] = sum(case when pageURL like '%ab%' THEN 1 else 0 END), 
       [cd]= sum(CASE WHEN pageURL LIKE '%cd%'THEN 1 ELSE 0 END)
FROM activityLog
GROUP BY USER,
         department,
         activity,
         DATENAME(mm, ActDateTime)+ ' - ' + 
         DATENAME(yy, ActDateTime)
ORDER BY USER,
         department,
         activity,
         DATENAME(mm, ActDateTime)+ ' - ' + DATENAME(yy, ActDateTime)

【问题讨论】:

    标签: sql sql-server sql-server-2008 group-by


    【解决方案1】:

    我认为这应该可以创建您的计数:

    SELECT
      cast(ActDateTime as Date) as DateOnly, 
      SUM(CASE WHEN PageUrl Like '%ab%' THEN 1 ELSE 0 END) as ABCount,
      SUM(CASE WHEN PageUrl Like '%cd%' THEN 1 ELSE 0 END) as CDCount
    FROM Table1 
    GROUP BY cast(ActDateTime as Date)
    

    SQL Fiddle

    【讨论】:

    • 不清楚逻辑,但是具体的实现,有一个小问题。 COUNT0s 和 1s 一样重要。意思是,您可能应该将两个0s 替换为NULLs(或简单地删除ELSE 子句)或将两个COUNTs 替换为SUMs。 IE。我可能不确定条件或分组标准或其他任何内容是否正确,但我可以看到您正在尝试进行条件聚合,而这正是问题所在。使用 COUNT,您应该规定 NULL 以省略计数,但如果您更喜欢使用 1 和 0,那么请改用 SUM。
    • @AndriyM 谢谢你,你绝对是对的,我没有经过实际测试就输入了,所以这次也包括了 sql fiddle。
    【解决方案2】:

    第一个查询以按天计算:

    SELECT cast(ActDateTime AS Date) AS DateOnly,
           CASE
               WHEN SUM(CASE WHEN PageUrl LIKE '%ab%' THEN 1 ELSE 0 END) >=1 THEN 1
               ELSE 0
           END AS ABCount,
           CASE
               WHEN SUM(CASE WHEN PageUrl LIKE '%cd%' THEN 1 ELSE 0 END) >=1 THEN 1
               ELSE 0
           END AS CDCount
    FROM activityLog
    GROUP BY cast(ActDateTime AS Date)
    

    第二次查询得到你想要的输出:

    SQLFIDDLEExample

    SELECT DATENAME(month, a.ActDateTime)+ ' - ' + DATENAME(yy, a.ActDateTime)
          ,SUM(a.ABCount) as ABCount
          ,SUM(a.CDCount) as CDCount
    FROM (SELECT cast(ActDateTime AS Date) AS ActDateTime,
           CASE
               WHEN SUM(CASE WHEN PageUrl LIKE '%ab%' THEN 1 ELSE 0 END) >=1 THEN 1
               ELSE 0
           END AS ABCount,
           CASE
               WHEN SUM(CASE WHEN PageUrl LIKE '%cd%' THEN 1 ELSE 0 END) >=1 THEN 1
               ELSE 0
           END AS CDCount
    FROM activityLog
    GROUP BY cast(ActDateTime AS Date))a
    GROUP BY DATENAME(month, a.ActDateTime)+ ' - ' + DATENAME(yy, a.actdatetime)
    ORDER BY DATENAME(month, a.ActDateTime)+ ' - ' + DATENAME(yy, a.actdatetime)
    

    结果:

    |       COLUMN_0 | ABCOUNT | CDCOUNT |
    --------------------------------------
    | January - 2013 |       2 |       1 |
    

    【讨论】:

      【解决方案3】:
      SELECT Thing
            ,COUNT(*) NumDays
      FROM  (SELECT LEFT(PageURL, 2) AS Thing
             ,DateTime
             FROM table
             ALL
             SELECT RIGHT(PageURL, 2)
                   ,DateTime
             FROM table) UniqueDays
      

      由于您在问题中使用了关键词,这将无法正常工作。

      一般来说,使用实际的列/表名更容易,因此答案可以反映这些 - 它可以避免混淆。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-07-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-08
        • 1970-01-01
        • 1970-01-01
        • 2019-03-27
        相关资源
        最近更新 更多