【问题标题】:How to use GROUPING function in SQL common table expression - CTE如何在 SQL 公用表表达式中使用 GROUPING 函数 - CTE
【发布时间】:2016-07-02 12:17:34
【问题描述】:

我有下面的 T-SQL CTE 代码,我正在尝试对四列(即产品、项目分类、名称和编号)进行一些行分组。

;WITH CTE_FieldData
AS (
    SELECT 
      CASE(GROUPING(M.CodeName))
            WHEN 0 THEN M.CodeName
            WHEN 1 THEN 'Total'
            END AS Product,

        CASE(GROUPING(KK.ItemClassification))
            WHEN 0 THEN KK.[ItemClassification]
            WHEN 1 THEN 'N/A'
            END AS [ItemClassification],

        CASE(GROUPING(C.[Name]))
            WHEN 0 THEN ''
            WHEN 1 THEN 'Category - '+ '('+ItemClassification+')'
            END AS [Name],

            CASE(GROUPING(PYO.Number))
            WHEN 0 THEN PYO.Number
            WHEN 1 THEN '0'
            END AS [Number],

        ISNULL(C.[Name],'') AS ItemCode,
        MAX(ISNULL(PYO.Unit, '')) AS Unit,
        MAX(ISNULL(BT.TypeName, '')) AS [Water Type],
        MAX(ISNULL(PYO.OrderTime, '')) AS OrderTime,
        MAX(ISNULL(BUA.Event, '')) AS Event,
        MAX(ISNULL(PYO.Remarks, '')) AS Remarks,
        GROUPING(M.CodeName) AS ProductGrouping,
        GROUPING(KK.ItemClassification) AS CategoryGrouping,
        GROUPING(C.[Name]) AS ItemGrouping
    FROM CTable C INNER JOIN CTableProducts CM ON C.Id = CM.Id
                INNER JOIN MyData R ON R.PId = CM.PId 
                INNER JOIN MyDataDetails PYO ON PYO.CId = C.CId AND PYO.ReportId = R.ReportId
                INNER JOIN ItemCategory KK ON C.KId = KK.KId
                INNER JOIN Product M ON R.ProductId = M.ProductId
                INNER JOIN WaterType BT ON PYO.WId = BT.WId
                INNER JOIN WaterUnit BUA ON PYO.WUId = BUA.WUId
                WHERE R.ReportId = 4360
    GROUP BY M.CodeName, KK.ItemClassification, C.Name, PYO.Number
    WITH ROLLUP
)
SELECT 
    Product, 
    [Name] AS Category,
    Number, 
    Unit as ItemCode, 
    [Water Type], 
    OrderTime, 
    [Event], 
    [Comment]
    FROM CTE_FieldData

以下是上面脚本返回的数据的问题/问题,它们是我正在尝试解决的问题。

  1. 在每个 ItemClassification 分组的末尾,添加了 i 个额外记录,但它在表中不存在。 (请参阅随附的示例查询结果屏幕截图中的第 4 行和第 10 行)。

  2. 我希望第 2 列中的 ItemClassification 分组位于组的开头而不是组的末尾。 这样,ItemClassification "Category- (One)" 将位于第 1 行,而不是当前的第 5 行。 ItemClassification "Category- (Two)" 也将在第 5 行而不是当前第 11 行

  3. 显示“ItemClassification”的位置我希望列(编号、ItemCode、[水类型]、[OrderTime]、[Event]、[Comment])显示为空。 在随附的示例查询结果屏幕截图中,这些将是第 11 行和第 5 行

  4. 最后一行 (13) 也是不需要的。

我正在尝试理解 SQL CTE 和 GROUPING 函数,但我没有做对。

【问题讨论】:

  • 这一切似乎都是展示类型的东西。这不应该留给前端吗?当最终用户对这些结果进行排序时会发生什么?

标签: sql-server tsql sql-server-2005


【解决方案1】:

看起来这主要是由 WITH ROLLUP 和 GROUPING 引起的。 ROLLUP 允许您为分组创建一个总和线。当您使用 WITH ROLLUP 时,它将为您的 select 语句中的所有非聚合字段提供 NULL 值。您将 GROUPING() 与 ROLLUP 结合使用,然后将这些 NULL 标记为“Total”或“0”或“Category”,就像您的查询一样。
1) 由 GROUPING 和 ROLLUP 引起。把两者都拿走,这应该得到解决。

2) 不确定是什么决定了您的组以及将什么定义为开始或结束。 Order BY 就足够了

3) 使用 ISNULL 或 CASE WHEN。如果项目分类有一个非空或非空值,NULL 每个字段出来。

4) 使用 ROLLUP 起飞。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-12
    • 1970-01-01
    • 1970-01-01
    • 2017-06-02
    • 2020-12-25
    • 1970-01-01
    相关资源
    最近更新 更多