添加列时HAVING子句不起作用(需要检查约束吗?)

时间:2013-03-11 16:11:10

标签: sql constraints having-clause

SQL#1给我回复了163个(通过HAVING子句),因为它给了我从2013年开始首次购买特定包裹(包102)的帐户。

现在我希望在2013年按财政月分解销售额,当我将[Unique_Fiscal_Month_Label]添加为列时,它会给我406个帐户,而HAVING子句现在基本上不起作用。请参见下面的SQL#2。添加Fiscal_Month的任何想法基本上都会给我所有曾经购买过这种包类型的帐户吗?我在网上看到,检查条件可能有所帮助,但写作没有运气。

SQL#1

SELECT 

sum([FactActualDetail].[CaseAndGallonVolume]) AS [CaseAndGallonVolume],
sum([FactActualDetail].[AdjGrossMarginAmount]) AS [AdjGrossMarginAmount],
left([FactActualDetail].[SourceCustomerProductCode],7) as [Acct #]

FROM [dbo].[FactActualDetail] [FactActualDetail] 

LEFT JOIN [dbo].[DimCustomer] [DimCustomer] 
    ON ([FactActualDetail].[CustomerSK] = [DimCustomer].[CustomerSK])
LEFT JOIN [Common].[DimDate] [DimDate] 
    ON ([FactActualDetail].[DeliveryDateSK] = [DimDate].[DateSK])

WHERE [EQMultiplier] > 0 AND ([SC] = 04 OR [SC] = 06 OR [SC] = 07) 
  AND (substring([SourceCustomerProductCode],8,3) = 102) 
  AND [Fiscal_Year] IN (2013, 2012)

GROUP BY left([FactActualDetail].[SourceCustomerProductCode],7)

HAVING MIN([Fiscal_Year])=2013

SQL#2

SELECT 

sum([FactActualDetail].[CaseAndGallonVolume]) AS [CaseAndGallonVolume],
sum([FactActualDetail].[AdjGrossMarginAmount]) AS [AdjGrossMarginAmount],
left([FactActualDetail].[SourceCustomerProductCode],7) as [Acct #],
[Unique_Fiscal_Month_Label] AS [Unique_Fiscal_Month_Label]

FROM [dbo].[FactActualDetail] [FactActualDetail] 

LEFT JOIN [dbo].[DimCustomer] [DimCustomer] 
    ON ([FactActualDetail].[CustomerSK] = [DimCustomer].[CustomerSK])
LEFT JOIN [Common].[DimDate] [DimDate] 
    ON ([FactActualDetail].[DeliveryDateSK] = [DimDate].[DateSK])

WHERE [EQMultiplier] > 0 AND ([SC] = 04 OR [SC] = 06 OR [SC] = 07) 
  AND (substring([SourceCustomerProductCode],8,3) = 102) 
  AND [Fiscal_Year] IN (2013, 2012)

GROUP BY 
  left([FactActualDetail].[SourceCustomerProductCode],7),
  [Unique_Fiscal_Month_Label]


HAVING MIN([Fiscal_Year])=2013

3 个答案:

答案 0 :(得分:0)

我们需要一些样本数据才能真正回答这个问题。但我猜测问题是你现在在SQL#2中按帐户和月份聚合,而SQL#1仅在帐户级别聚合。而且由于您的HAVING条款,您基本上过滤了2013年客户的所有销售,而在您仅过滤2013年首次销售的客户之前。

您应该能够使用子查询来完成逻辑,即

SELECT [Unique_Fiscal_Month_Label] AS [Unique_Fiscal_Month_Label]
    , x.[CaseAndGallonVolume]
    , x.[AdjGrossMarginAmount]
    , x.[Acct #]
FROM (
    SELECT 
    sum([FactActualDetail].[CaseAndGallonVolume]) AS [CaseAndGallonVolume],
    sum([FactActualDetail].[AdjGrossMarginAmount]) AS [AdjGrossMarginAmount],
    left([FactActualDetail].[SourceCustomerProductCode],7) as [Acct #],
    MIN([FactActualDetail].[DeliveryDateSK]) AS [minDeliveryDateSK]
    FROM [dbo].[FactActualDetail] [FactActualDetail] 
    LEFT JOIN [dbo].[DimCustomer] [DimCustomer] 
        ON ([FactActualDetail].[CustomerSK] = [DimCustomer].[CustomerSK])
    WHERE [EQMultiplier] > 0 AND ([SC] = 04 OR [SC] = 06 OR [SC] = 07) 
      AND (substring([SourceCustomerProductCode],8,3) = 102) 
      AND [Fiscal_Year] IN (2013, 2012)
    GROUP BY left([FactActualDetail].[SourceCustomerProductCode],7)
    HAVING MIN([Fiscal_Year])=2013
) AS x
LEFT JOIN [Common].[DimDate] [DimDate] 
    ON ([x].[minDeliveryDateSK] = [DimDate].[DateSK]);

如果没有实际数据,这只是猜测查询的外观,但希望它可以让您了解如何继续。 HTH。祝好运。

答案 1 :(得分:0)

您的having条款不再有效,因为每个组仅适用于一个帐户的一个会计月,因此您将无法确定哪些帐户在2012年的群组中具有2013年的活动。 ,尝试在整个时期使用分析功能 - 如:

SELECT sum([CaseAndGallonVolume]) AS [CaseAndGallonVolume],
       sum([AdjGrossMarginAmount]) AS [AdjGrossMarginAmount],
       [Acct #],
       [Unique_Fiscal_Month_Label]
FROM (SELECT [FactActualDetail].[CaseAndGallonVolume],
             [FactActualDetail].[AdjGrossMarginAmount]),
             left([FactActualDetail].[SourceCustomerProductCode],7) as [Acct #],
             [Unique_Fiscal_Month_Label],
             min([Fiscal_Year]) over (prtition by left([FactActualDetail].[SourceCustomerProductCode],7)) as min_year
      FROM [dbo].[FactActualDetail] [FactActualDetail] 
      LEFT JOIN [dbo].[DimCustomer] [DimCustomer] 
             ON ([FactActualDetail].[CustomerSK] = [DimCustomer].[CustomerSK])
      LEFT JOIN [Common].[DimDate] [DimDate] 
             ON ([FactActualDetail].[DeliveryDateSK] = [DimDate].[DateSK])
      WHERE [EQMultiplier] > 0 AND ([SC] = 04 OR [SC] = 06 OR [SC] = 07) 
        AND (substring([SourceCustomerProductCode],8,3) = 102) 
        AND [Fiscal_Year] IN (2013, 2012)
     ) sq
WHERE min_year=2013
GROUP BY 
       [Acct #],
       [Unique_Fiscal_Month_Label]

答案 2 :(得分:0)

我假设Fiscal_Year在[Common]。[DimDate]表

SELECT sum([FactActualDetail].[CaseAndGallonVolume]) AS [CaseAndGallonVolume],
       sum([FactActualDetail].[AdjGrossMarginAmount]) AS [AdjGrossMarginAmount],
       left([FactActualDetail].[SourceCustomerProductCode],7) as [Acct #],
       [Unique_Fiscal_Month_Label] AS [Unique_Fiscal_Month_Label]
FROM [dbo].[FactActualDetail] [FactActualDetail] 
  LEFT JOIN [dbo].[DimCustomer] [DimCustomer] 
    ON ([FactActualDetail].[CustomerSK] = [DimCustomer].[CustomerSK])
  LEFT JOIN [Common].[DimDate] [DimDate] 
    ON ([FactActualDetail].[DeliveryDateSK] = [DimDate].[DateSK])
WHERE [EQMultiplier] > 0 AND ([SC] = 04 OR [SC] = 06 OR [SC] = 07) 
  AND (substring([SourceCustomerProductCode],8,3) = 102) 
  AND [Fiscal_Year] = 2013 AND EXISTS (
                                       SELECT 1
                                       FROM [Common].[DimDate] AS [DimDate2]  
                                       WHERE [DimDate].[DateSK] = [DimDate2].[DateSK]
                                       HAVING MIN([DimDate2].Fiscal_Year) != 2012
                                       )                                         
GROUP BY 
  left([FactActualDetail].[SourceCustomerProductCode],7),
  [Unique_Fiscal_Month_Label]

简单示例我在SQLFiddle

上的含义