【问题标题】:SQL over partition count then group by monthSQL 在分区计数上然后按月分组
【发布时间】:2014-05-22 19:59:19
【问题描述】:

我一直在使用COUNT(value) OVER (PARTITION BY anothervalue),我喜欢它从我的数据库中提取结果的速度有多快。我现在正试图加快步伐,以便我可以创建一个表格来显示多个计数 - 每个月一个,并排。我不确定是否可能,但想在这里查看。我在网上浏览了一下,但找不到任何以前提出过的问题的例子,所以没有线索。

这是我目前拥有的:

SELECT DISTINCT
TBL.CATEGORY as 'Category Name',
COUNT(TBL.ROW_ID) OVER (PARTITION BY TBL.CATEGORY) as 'Rows in Category'
FROM
MYDB.TBL
WHERE
TBL.FIELD1 = 'something'
AND TBL.FIELD2 = 'somethingelse'
AND TBL.CREATED >= '2014-01-01'
ORDER BY [Rows in Category] desc

给了我这样一张可爱的桌子:

Category Name |Rows in Category
 ABC          | 166
 CBA          | 137
 CCC          | 112

我现在想要得到的是按月细分,所以我的输出最终看起来像这样(不一定要准确,标题可以随机播放):

JANUARY                          |FEBRUARY
 Category Name |Rows in Category | Category Name |Rows in Category 
  ABC          | 162             |  CBA          | 51
  CBA          | 86              |  CCC          | 32               
  CCC          | 70              |  ABC          | 4

当我尝试添加 GROUP BY 时,它会引发关于聚合函数中未包含某些内容的错误。

如果必须,我可以将查询堆叠在一起,并将每个查询限制为仅显示一个月,但这似乎是很多重复的代码,如果可以的话,我更喜欢并排查看完成。

有什么想法吗?

【问题讨论】:

    标签: sql sql-server count group-by window-functions


    【解决方案1】:

    格式与您描述的不完全相同。但这将是显示结果的正常方式,并且所有信息都已包含在内,请确保一次显示的时间不超过 1 年。

    试试这个:

    ;WITH x AS
    (
       SELECT TBL.CATEGORY, TBL.ROW_ID, datename(month, TBL.CREATED) month
       FROM
          MYDB.TBL
       WHERE
          TBL.FIELD1 = 'something'
          AND TBL.FIELD2 = 'somethingelse'
          AND TBL.CREATED >= '2014-01-01'
          AND TBL.CREATED < '2015-01-01'
    )
    SELECT CATEGORY as 'Category Name', [January],[February]
    FROM x
       PIVOT(
          count([ROW_ID])  
          FOR month
          in([January],[February])  
       )AS p
    

    【讨论】:

    • 理想!这就是诀窍。有没有办法按总计数降序对类别进行排序?
    • @joe 在脚本末尾添加“按类别排序”
    • 这似乎是按类别名称的字母顺序排序的,我希望按计数排序(最大优先)。不过不用担心,我已经对结果很满意了。
    • @joe 你也可以通过 coalesce([January])+coalesce(([February]) 编写订单
    【解决方案2】:

    @t-clausen.dk 感谢您的帮助。我以前没有使用过 coalesce,所以今天我学到了一些有用的东西。最后,因为我发现无论如何我都需要一个总列,所以我添加了一个 YTD 列并能够按此排序。

    想发布最终结果以防其他人使用:

    WITH X AS
    
    (
    SELECT 
    tbl.category,
    tbl.row_id,
    DATENAME(MONTH, tbl.created) MONTH,
    COUNT(tbl.row_id) OVER (PARTITION BY tbl.category) AS 'YTD'
    FROM
    db.tbl
    WHERE
    tbl.randomcolumn = 'something specific'
    AND tbl.anothercolumn = 'something else specific'
    AND created >= '2014-01-01'
    AND created < '2015-01-01'
    )
    
    SELECT
    category AS 'Category Name',
    [January], [February], [March], [April], [May], [June], [July], [August], [September], [October], [November], [December],
    [YTD]
    FROM X
    
       PIVOT
       (COUNT([row_id]) 
       FOR MONTH
       in([January], [February], [March], [April], [May], [June], [July], [August], [September], [October], [November], [December])
       )AS P
    
    ORDER BY [YTD] DESC
    

    如果希望重新调整此查询的用途,请在您自己的 db/table 中为等效项切换小写部分。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-26
      • 2023-02-13
      • 2016-11-26
      • 2012-09-03
      相关资源
      最近更新 更多