【问题标题】:How do I add missing Months?如何添加缺失的月份?
【发布时间】:2013-06-19 16:48:25
【问题描述】:

我有一个查询,按会计月份按客户提取销售额。但是,我有一些客户在给定的月份内没有购买。对于这些情况,我希望 MonthNum 字段的 SalesDlr 值为 0,但 MonthNum 值仍需要是实际的月份编号。目前,我在下面的查询中没有得到 MonthNum 值:

SELECT
    a.Customer,
    a.CustomerName,
    a.MonthNum,
    a.FiscalYear,
    a.SalesDlr
FROM
(SELECT
    sd.SBCUST AS Customer,
    sd.RMNAME AS CustomerName,
    fc.FiscalMonthNum AS MonthNum,
    fc.FiscalYear,
    SUM(sd.SBEPRC) AS SalesDlr
FROM
    dbo.SalesData sd
    LEFT OUTER JOIN dbo.FiscalCalendar fc ON fc.FiscalDate = sd.SBINDT
WHERE
    sd.SBTYPE = 'O'
AND
    sd.SBINDT > '2012-12-31'
AND
    sd.SBCLS NOT IN ('1500')
GROUP BY
    sd.SBCUST,
    sd.RMNAME,
    fc.FiscalMonthNum,
    fc.FiscalYear
)a
GROUP BY
    a.Customer,
    a.CustomerName,
    a.MonthNum,
    a.FiscalYear,
    a.SalesDlr
ORDER BY
    a.Customer,
    a.MonthNum,
    a.FiscalYear

我该如何解决这个问题?

【问题讨论】:

  • " 对于这些情况,我希望 MonthNum 字段的值为 0 " .... 你确定吗??还是您希望 SalesDlr 为 0
  • 我希望 SalesDlr 为 0,但我还需要 MonthNum 字段为没有销售的月份设置一个值。例如,客户 ABC 是否在 2013 年 4 月开始购买,那么我需要 2013 年 1 月的 SalesDlr 值以及 2 月和 3 月为 0。
  • 您的查询不应该然后 FiscalCalendar 离开加入 SalesData 吗?似乎您想要没有销售的月份,因此切换订单是有意义的。
  • 这仍然给了我相同的结果。

标签: tsql sql-server-2012-express


【解决方案1】:

我猜您的 SalesData 每个月都没有每个客户的条目。如果客户 Curtis 在 5 月份没有进行购买,那么他可能在 5 月份的 SalesData 中没有任何条目。因此,当您使用左侧的 SalesData 离开 join 时,Curtis 将不会有 May 的一行。

切换左连接的顺序也是不够的,因为这只会为丢失的客户生成一个日期。因此,您确实希望在不同的客户和不同的月份之间进行交叉连接,然后得到它们的总和:

with FilteredSalesData as (
    SELECT  
        sd.SBCUST as Customer,
        sd.RMName as CustomerName,
        sd.SBEPRC,
        fc.FiscalMonthNum as MonthNum,
        fc.FiscalYear
    FROM dbo.SalesData sd
    join FiscalCalendar fc ON fc.FiscalDate = sd.SBINDT
        WHERE
            sd.SBTYPE = 'O'
        AND
            sd.SBCLS NOT IN ('1500')
), DistinctCustomers as (
    select distinct 
        SBCUST as Customer,
        RMName as CustomerName
    from FilteredSalesData
), DistinctMonths as (
    select distinct
        FiscalMonthNum as MonthNum,
        FiscalYear
    From FiscalCalendar
    WHERE FiscalDate > '2012-12-31'
)
select
    Customer,
    CustomerName,
    MonthNum,
    FiscalYear,
    SUM(sd.SBEPRC) as SalesDlr
From DistinctCustomers dc
CROSS JOIN DistinctMonths dm
left Join FilteredSalesData sd 
    on sd.customer = dc.Customer 
    and sd.CustomerName = dc.CustomerName
    and sd.MonthNum = dm.MonthNum
    and sd.FiscalYear = dm.FiscalYear
group by Customer, CustomerName, MonthNum, FiscalYear
order by Customer, MonthNum, FiscalYear

【讨论】:

  • 您在声明中是正确的,它没有每个月的每个客户的条目。但是,您的回答仍然没有产生预期的结果。
  • @tsqln00b 好点。我错过了 where 过滤器。您可以在联接之前先使用子查询过滤 SalesData。回到电脑前,我将编辑我的解决方案。
  • @tsqln00b 我已经用子查询中的过滤器更新了解决方案。使用外部过滤器,它将过滤掉所有保留连接的 NULL 行。
  • 在没有销售的一个月内我仍然没有得到 0 值。
  • 我正在寻找的是: 123 Acme Co. 1 2013 $10000 123 Acme Co. 2 2013 $5000 123 Acme Co. 3 2013 $0 123 Acme Co. 4 2013 $5000 123 Acme Co. 5 2013 年 7500 美元 123 Acme Co. 6 2013 年 0 美元。当我运行查询时,我在第 3 个月和第 6 个月都没有得到结果。
猜你喜欢
  • 2013-06-24
  • 1970-01-01
  • 2017-07-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-20
  • 1970-01-01
相关资源
最近更新 更多