1

我正在 SQL Server 2019 开发人员版上运行以下脚本。您可以在自己的 SQL Server 上运行它,任何数据库都可以(不需要特定的架构)。

在我的脚本底部,我在 GROUP BY 子句中有一个包含 2 个分组集的查询。第二个分组集包含一个表达式作为分组集中的唯一列,我在 SELECT 子句中将相同的表达式输出为名为“Month”的列。作为此 Grouping Set 的结果呈现的行将此 Month 列输出为 NULL。

我不希望这样。我预计任何输出与分组集中指定的列相同的列都应该包含该组的行被分组的值。简而言之,我的结果集中的每一行都应该在 Month 列中有一个值,因为该列的表达式在我的两个分组集中。

我想错了吗?通过运行此脚本在您的 SQL Server 上尝试...

查询:

IF OBJECT_ID('tempdb..#InventoryItemBatch') IS NOT NULL
    DROP TABLE #InventoryItemBatch
CREATE TABLE #InventoryItemBatch
(
    [Id] [bigint] IDENTITY(1,1) NOT NULL,
    [Quantity] [int] NOT NULL,
    [BatchNumber] [varchar](200) NULL,
    [InventoryDate] [date] NOT NULL,
    [QuantityRemoved] [int] NOT NULL,
    [QuantityRemaining]  AS ([Quantity]-[QuantityRemoved]),
    [PricePerUnit] [decimal](18, 2) NULL,
)

SET NOCOUNT ON
SET IDENTITY_INSERT #InventoryItemBatch ON

MERGE INTO #InventoryItemBatch AS Target
USING (VALUES
  (144,543,'Q','1980-11-17',543,751.24)
 ,(1274,1,'S1','1980-08-17',0,0.00)
 ,(1469,609,'QA','1980-06-27',609,778.05)
 ,(1470,95,'QC','1980-11-24',95,887.99)
 ,(1473,120,'QB','1980-11-14',120,867.20)
 ,(1475,231,'QE','1980-05-15',231,783.09)
 ,(1476,109,'Q','1980-04-10',109,778.05)
 ,(1552,1,'S1','1980-05-28',0,3465.00)
 ,(3082,1,'S1','1980-05-30',0,20020.00)
 ,(4396,1,'S1','1980-05-31',0,3465.00)
 ,(4702,1,'S1','1980-08-17',0,0.00)
 ,(5114,1,'S1','1980-08-17',0,0.00)
 ,(5337,1,'S1','1978-04-07',0,1250.00)
 ,(5549,1,'S1','1980-08-17',0,0.00)
 ,(6152,1,'S1','1980-08-17',0,0.00)
 ,(6233,1,'S1','1980-07-22',0,0.00)
 ,(7616,1,'S1','1980-08-17',0,0.00)
 ,(9444,1,'S1','1980-04-30',0,3465.00)
 ,(10821,1,'S1','1980-05-21',0,1480.00)
 ,(11299,1,'S1','1980-09-14',0,1700.00)
 ,(17432,1,'S1','1980-02-18',0,1222.00)
 ,(20492,1,'S1','1980-02-12',0,2040.00)
 ,(22588,1,'S1','1980-01-01',0,0.00)
 ,(26842,1,'S1','1980-04-30',0,1593.00)
 ,(34323,1,'S1','1980-03-27',0,1219.00)
 ,(34334,1,'S1','1980-05-31',0,1219.00)
 ,(35223,1,'S1','1980-01-01',0,0.00)
 ,(35379,1,'S1','1980-02-18',0,1222.00)
 ,(36384,1,'S1','1980-04-30',0,3465.00)
 ,(36395,1,'S1','1980-07-13',0,1219.00)
 ,(43278,1,'S1','1978-06-09',0,850.00)
 ,(43998,1,'S1','1978-08-18',0,935.00)
 ,(47460,1,'S1','1978-03-15',0,2276.00)
 ,(47944,1,'S1','1978-04-07',0,0.00)
 ,(48926,1,'S1','1978-09-28',0,1350.00)
 ,(49166,1,'S1','1978-05-12',0,1602.00)
 ,(49248,1,'S1','1978-09-28',0,0.00)
 ,(49300,1,'S1','1978-05-12',0,0.00)
 ,(57492,1,'S1','1978-06-09',0,850.00)
 ,(57499,1,'S1','1979-06-30',0,963.00)
 ,(57524,1,'S1','1980-03-03',0,0.00)
) AS Source ([Id],[Quantity],[BatchNumber],[InventoryDate],[QuantityRemoved],[PricePerUnit])
ON (Target.[Id] = Source.[Id])
WHEN NOT MATCHED BY TARGET THEN
 INSERT([Id],[Quantity],[BatchNumber],[InventoryDate],[QuantityRemoved],[PricePerUnit])
 VALUES(Source.[Id],Source.[Quantity],Source.[BatchNumber],Source.[InventoryDate],Source.[QuantityRemoved],Source.[PricePerUnit])
;

SET IDENTITY_INSERT #InventoryItemBatch  OFF
SET NOCOUNT OFF


-- offending query
SELECT
    'Grouping-Month' = GROUPING(CONVERT(VARCHAR,YEAR(iib.InventoryDate)) + '.' + CONVERT(VARCHAR,FORMAT(iib.InventoryDate, 'MM')))
    , 'Grouping-Id' = GROUPING(iib.Id)
    , 'Grouping-DatePurchased' = GROUPING(iib.InventoryDate)

      -- this column should have a value in *eveny* row but is missing values for rows produced by the second grouping set
    , [Month] = CONVERT(VARCHAR,YEAR(iib.InventoryDate)) + '.' + CONVERT(VARCHAR,FORMAT(iib.InventoryDate, 'MM'))

    , Id = iib.Id
    , DatePurchased = iib.InventoryDate
    , SumPurchaseAmt = Sum(iib.PricePerUnit * iib.Quantity)

FROM #InventoryItemBatch iib
GROUP BY
    GROUPING SETS (
        (
            CONVERT(VARCHAR,YEAR(iib.InventoryDate)) + '.' + CONVERT(VARCHAR,FORMAT(iib.InventoryDate, 'MM'))
            , iib.Id
            , iib.InventoryDate
        )
        , (
            -- this is the grouping expression that I'm not seeing a value for
            CONVERT(VARCHAR,YEAR(iib.InventoryDate)) + '.' + CONVERT(VARCHAR,FORMAT(iib.InventoryDate, 'MM'))
        )
    )

部分输出:

在此处输入图像描述

附加信息:

我还注意到,如果您从第一个分组集中删除“iib.InventoryDate”列并从 SELECT 子句中删除它),它实际上解决了我在这里提到的问题......输出的行第二分组集实际上现在确实包含月份列中的那些缺失值。诡异的!!(正确的?)

这对我来说就像一个错误。我是不是误会了?

4

1 回答 1

0

重写查询,以便[Month]显式引入

with cte as (
    select  [Id] ,
    [Quantity] ,
    [BatchNumber] ,
    [InventoryDate] ,
    [QuantityRemoved] ,
    [QuantityRemaining] ,
    [PricePerUnit],
    [Month] = CONVERT(VARCHAR,YEAR(InventoryDate)) + '.' + CONVERT(VARCHAR,FORMAT(InventoryDate, 'MM'))
    from #InventoryItemBatch     
)

-- offending query
SELECT
    'Grouping-Month' = GROUPING([Month])
    , 'Grouping-Id' = GROUPING(iib.Id)
    , 'Grouping-DatePurchased' = GROUPING(iib.InventoryDate)
    , [Month]
    , Id = iib.Id
    , DatePurchased = InventoryDate
    , SumPurchaseAmt = Sum(iib.PricePerUnit * iib.Quantity)

FROM cte iib
GROUP BY
    GROUPING SETS (
        (
              iib.Id
            , iib.InventoryDate
            , [Month]   
        )
        , (
              [Month]
        )
    ); 
于 2020-11-04T20:13:32.347 回答