【问题标题】:SQL return custom groups with 0 entriesSQL 返回具有 0 个条目的自定义组
【发布时间】:2011-04-27 17:37:53
【问题描述】:

我有一个查询要转储到条形图 RDLC 中。我希望查询能够完成所有繁重的工作。现在我的查询看起来像这样:

SELECT id, 
       CASE 
         WHEN a.sc < 50 THEN '1: Less than 50' 
         WHEN a.sc >= 50 
              AND a.sc < 100 THEN '2: 50 - 100' 
         WHEN a.sc >= 100 
              AND a.sc < 150 THEN '3: 100 - 150' 
         WHEN a.sc >= 150 
              AND a.sc < 200 THEN '4: 150 - 200' 
         WHEN a.sc >= 200 
              AND a.sc < 250 THEN '5: 200 - 250' 
         WHEN a.sc >= 250 THEN '6: Greater than 250' 
         ELSE '7: Unable to calculate' 
       END AS [range]
FROM   (SOME_SUB_QUERY) AS a
ORDER BY [range]

如您所见,我有一些自定义的分组。示例结果集如下所示:

[ID]     [range]
18       4: 150 - 200
1237     6: Greater than 250
665      7: Unable to calculate
121      7: Unable to calculate

我的 RDLC 正在按范围对结果进行分组,然后制作一个条形图。问题是如果组中没有项目,则条形图缺少组。

鉴于上面的结果,我希望查询返回以下内容,以便图表始终包含所有组:

[count]     [range]
0           1: Less than 50
0           2: 50 - 100
0           3: 100 - 150
1           4: 150 - 200
0           5: 200 - 250
1           6: Greater than 250
2           7: Unable to calculate

我假设我需要将查询包装在另一个查询中,该查询执行分组并添加空组,但我不知道如何使其工作。

【问题讨论】:

  • 这是 SQL Server 吗?如果有,是什么版本?

标签: sql grouping


【解决方案1】:

你可以试试这个。这使您可以创建left join 上的虚拟查找。然后,您可以按 rtext 分组并计算 RDLC 中 a 的结果。

如果您的 DB 支持它 PIVOTCTE 可能会使它更干净

SELECT id, 
       CASE 
         WHEN a.sc < 50 THEN '1: Less than 50' 
         WHEN a.sc >= 50 
              AND a.sc < 100 THEN '2: 50 - 100' 
         WHEN a.sc >= 100 
              AND a.sc < 150 THEN '3: 100 - 150' 
         WHEN a.sc >= 150 
              AND a.sc < 200 THEN '4: 150 - 200' 
         WHEN a.sc >= 200 
              AND a.sc < 250 THEN '5: 200 - 250' 
         WHEN a.sc >= 250 THEN '6: Greater than 250' 
         ELSE '7: Unable to calculate' 
       END AS [range] 
FROM   (SELECT '1: Less than 50' AS rtext 
        UNION 
        SELECT '2: 50 - 100' 
        UNION 
        SELECT '3: 100 - 150' 
        UNION 
        SELECT '4: 150 - 200' 
        UNION 
        SELECT '5: 200 - 250' 
        UNION 
        SELECT '6: Greater than 250' 
        UNION 
        SELECT '7: Unable to calculate') range 
       LEFT JOIN some_sub_query AS a 
         ON range.rtext = ( CASE 
                              WHEN a.sc < 50 THEN '1: Less than 50' 
                              WHEN a.sc >= 50 
                                   AND a.sc < 100 THEN '2: 50 - 100' 
                              WHEN a.sc >= 100 
                                   AND a.sc < 150 THEN '3: 100 - 150' 
                              WHEN a.sc >= 150 
                                   AND a.sc < 200 THEN '4: 150 - 200' 
                              WHEN a.sc >= 200 
                                   AND a.sc < 250 THEN '5: 200 - 250' 
                              WHEN a.sc >= 250 THEN '6: Greater than 250' 
                              ELSE '7: Unable to calculate' 
                            END ) 
ORDER  BY [range] 

【讨论】:

  • 感谢您的回复。我选择了另一个,因为它更简洁。
【解决方案2】:

假设SC是一个整数:

Select Ranges.Name
    , Count( Z.SomeNonNullableCol )
From    (
        Select '1: Less than 50'  As Name, 0 As Min, 49 As Max
        Union All Select '2: 50 - 100', 50, 99
        Union All Select '3: 100 - 150', 100, 149
        Union All Select '4: 150 - 200', 150, 199
        Union All Select '5: 200 - 250', 200, 259 
        Union All Select '6: Greater than 250', 250, 2147483647
        Union All Select '7: Unable to calculate', -2147483648, -1
        ) As Ranges
    Left Join ( Some Subquery ) As Z
        On Z.SC Between Ranges.Min And Ranges.Max
            Or ( Z.SC Is Null And Ranges.Max = -1 )
Group By Ranges.Name

【讨论】:

  • 我认为问题在于,如果没有 a.sc &lt;50 的值,那么该“范围”将不会以零计数出现在报告中
  • @Conrad Fix - 我明白了。是的,您需要枚举组并加入数据。
  • @Conrad Frix - 感谢您的提醒。我已经修改了我的答案并给了你一个 +1。
  • 完美。正是我想要的。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-12-16
  • 2021-01-25
  • 1970-01-01
  • 2015-11-13
  • 2020-01-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多