【问题标题】:Display count in dynamic ranges in SQL Server在 SQL Server 中以动态范围显示计数
【发布时间】:2021-07-05 02:19:17
【问题描述】:

我正在根据表中的最大值创建范围。例如,如果表中的最大值为 45,那么它将创建 0-10 11-20 21-30 31-40 41-50 之类的范围,然后希望在该范围内显示计数。下面是我在 SQL 中尝试的内容

DECLARE @VariableData TABLE (id INT, [label] NVARCHAR(50), PendingDays INT )

INSERT INTO @VariableData (id, [label], PendingDays) VALUES(1, 'Red', 5)
INSERT INTO @VariableData (id, [label], PendingDays) VALUES(2, 'Green', 7)
INSERT INTO @VariableData (id, [label], PendingDays) VALUES(3, 'Yellow', 25)
INSERT INTO @VariableData (id, [label], PendingDays) VALUES(4, 'Brown', 27)
INSERT INTO @VariableData (id, [label], PendingDays) VALUES(5, 'Black', 45)
INSERT INTO @VariableData (id, [label], PendingDays) VALUES(6, 'Red', 8)
INSERT INTO @VariableData (id, [label], PendingDays) VALUES(7, 'Red', 11)
INSERT INTO @VariableData (id, [label], PendingDays) VALUES(8, 'Green', 22)
INSERT INTO @VariableData (id, [label], PendingDays) VALUES(9, 'Black', 1)

SELECT * 
FROM @VariableData

我得到这个结果:

我想显示如下结果

有什么帮助吗?

【问题讨论】:

    标签: sql sql-server-2012


    【解决方案1】:

    您可以计算范围,然后根据范围的计算分为五组:

    select vd.*,
           floor((pendingdays - min_pendingdays) * 5.0 / (max_pendingdays - min_pendingdays + 1)) as tile
    from (select vd.*,
                 min(pendingdays) over () as min_pendingdays,
                 max(pendingdays) over () as max_pendingdays
          from VariableData vd
         ) vd;
    

    这会将结果放在中。您可以将这些聚合到列中:

    select label,
           sum(case when tile = 0 then 1 end) as tile_1,
           sum(case when tile = 1 then 1 end) as tile_2,
           sum(case when tile = 2 then 1 end) as tile_3,
           sum(case when tile = 3 then 1 end) as tile_4,
           sum(case when tile = 4 then 1 end) as tile_5
    from (select vd.*,
                 floor((pendingdays - min_pendingdays) * 5.0 / (max_pendingdays - min_pendingdays + 1)) as tile
          from (select vd.*,
                       min(pendingdays) over () as min_pendingdays,
                       max(pendingdays) over () as max_pendingdays
                from VariableData vd
               ) vd
         ) vd
    group by label;
    

    唯一需要注意的是,您不能根据数据中的值来命名列。这需要动态 SQL。

    Here 是一个 dbfiddle。

    【讨论】:

      【解决方案2】:

      最简单的方法是将 CASE 与聚合一起使用。

      SELECT [label], 
             SUM(CASE WHEN Pending Days BETWEEN 0 AND 10 THEN 1 ELSE 0 END) AS [0-10],
             SUM(CASE WHEN Pending Days BETWEEN 11 AND 20 THEN 1 ELSE 0 END) AS [11-20]
      FROM @VariableData
      GROUP BY [label]
      

      【讨论】:

      • 很酷,但范围是基于表的最大值动态的,而且我必须计算该范围内的待处理天数行
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多