如何在SQL公用表表达式中使用GROUPING函数 - CTE

时间:2016-03-16 14:33:49

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

我有下面的T-SQL CTE代码,我试图在四列上进行一些行分组,即Product,ItemClassification,Name&号。

;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分组结束时,我正在添加额外记录,但表中不存在。 (请参阅附带的示例查询结果屏幕截图中的第4行和第10行。)

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

  3. 在显示“ItemClassification”的情况下,我希望列(Number,ItemCode,[Water Type],[OrderTime],[Event],[Comment])显示为null。 在附加的样本查询结果屏幕截图中,那些将是行11和11。 5

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

  5. 我正在尝试理解SQL CTE和GROUPING函数,但我没有把事情搞定。

    enter image description here

1 个答案:

答案 0 :(得分:1)

看起来这主要是由WITH ROLLUP和GROUPING引起的。 ROLLUP允许您为分组创建基本上的总和。当您使用WITH ROLLUP时,它将为您的select语句中的所有非聚合字段提供NULL值。您将GROUPING()与ROLLUP结合使用,然后将这些NULL标记为' Total'或者' 0' 0或者'类别'正如你的查询所做的那样 1)由GROUPING和ROLLUP引起。带走两者,这应该得到解决。

2)不确定是什么决定了你的团队以及什么将被定义为开始或结束。订单BY应该足够了

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

4)用ROLLUP起飞。