按日期划分的财务数据组,即使数据为空

时间:2017-02-12 10:39:10

标签: sql sql-server

我在一个月内从SQL中提取财务数据,我希望得到一个月中每一天的数据集,以及旁边的数据。有些日子,这些数字将为空,这就是为什么如果我在日期对某个组执行查询,它只会返回包含数据的行。

╔════════════╦═════════════╗
║ Date       ║ DailyActual ║
╠════════════╬═════════════╣
║ 1/02/2017  ║ 14397.59091 ║
╠════════════╬═════════════╣
║ 2/02/2017  ║ 29723.37273 ║
╠════════════╬═════════════╣
║ 3/02/2017  ║ 32436.31818 ║
╠════════════╬═════════════╣
║ 6/02/2017  ║ 27048.32727 ║
╠════════════╬═════════════╣
║ 7/02/2017  ║ 30690.66364 ║
╠════════════╬═════════════╣
║ 8/02/2017  ║ 32267.42727 ║
╠════════════╬═════════════╣
║ 9/02/2017  ║ 29592.29091 ║
╠════════════╬═════════════╣
║ 10/02/2017 ║ 31740.49091 ║
╚════════════╩═════════════╝

我希望像这样返回数据

╔════════════╦═════════════╗
║ Date       ║ DailyActual ║
╠════════════╬═════════════╣
║ 1/02/2017  ║ 14397.59091 ║
╠════════════╬═════════════╣
║ 2/02/2017  ║ 29723.37273 ║
╠════════════╬═════════════╣
║ 3/02/2017  ║ 32436.31818 ║
╠════════════╬═════════════╣
║ 4/02/2017  ║             ║
╠════════════╬═════════════╣
║ 5/02/2017  ║             ║
╠════════════╬═════════════╣
║ 6/02/2017  ║ 27048.32727 ║
╠════════════╬═════════════╣
║ 7/02/2017  ║ 30690.66364 ║
╠════════════╬═════════════╣
║ 8/02/2017  ║ 32267.42727 ║
╠════════════╬═════════════╣
║ 9/02/2017  ║ 29592.29091 ║
╠════════════╬═════════════╣
║ 10/02/2017 ║ 31740.49091 ║
╠════════════╬═════════════╣
║ 11/02/2017 ║             ║
╠════════════╬═════════════╣
║ 12/02/2017 ║             ║
╠════════════╬═════════════╣
║ 13/02/2017 ║             ║
╠════════════╬═════════════╣
║ 14/02/2017 ║             ║
╠════════════╬═════════════╣
║ 15/02/2017 ║             ║
╠════════════╬═════════════╣
║ 16/02/2017 ║             ║
╠════════════╬═════════════╣
║ 17/02/2017 ║             ║
╠════════════╬═════════════╣
║ 18/02/2017 ║             ║
╠════════════╬═════════════╣
║ 19/02/2017 ║             ║
╠════════════╬═════════════╣
║ 20/02/2017 ║             ║
╠════════════╬═════════════╣
║ 21/02/2017 ║             ║
╠════════════╬═════════════╣
║ 22/02/2017 ║             ║
╠════════════╬═════════════╣
║ 23/02/2017 ║             ║
╠════════════╬═════════════╣
║ 24/02/2017 ║             ║
╠════════════╬═════════════╣
║ 25/02/2017 ║             ║
╠════════════╬═════════════╣
║ 26/02/2017 ║             ║
╠════════════╬═════════════╣
║ 27/02/2017 ║             ║
╠════════════╬═════════════╣
║ 28/02/2017 ║             ║
╚════════════╩═════════════╝

我设法编写了一个查询,可以选择当月的所有日期,但我无法通过我的财务查询加入此项?

DECLARE @startDate DATETIME= '20170201'
DECLARE @endDate DATETIME = '20170228'
;WITH Calender AS 
(
    SELECT @startDate AS CalanderDate
    UNION ALL
    SELECT CalanderDate + 1 FROM Calender
    WHERE CalanderDate + 1 <= @endDate
)
SELECT CalanderDate
FROM Calender
OPTION (MAXRECURSION 0)

根据我的第一张表格,我当前的查询如下

SELECT ci.InvoiceDate, SUM(CASE WHEN ci.Type = 'Invoice' THEN ci.Total ELSE -ci.Total END) / 1.1 
  FROM CustomerInvoice ci 
  WHERE ci.IsVoided = 0 AND ci.InvoiceDate BETWEEN '20170201' AND '20170228'
  GROUP BY ci.InvoiceDate

2 个答案:

答案 0 :(得分:1)

您从日历表到财务表left join。这将包括日历表中的所有行,可选地对财务表中的任何行重复。例如:

DECLARE @startDate DATETIME= '20170201'
DECLARE @endDate DATETIME = '20170228'
;
WITH    Calendar AS 
        (
        SELECT  @startDate AS CalendarDate
        UNION ALL
        SELECT  CalendarDate + 1 FROM Calendar
        WHERE   CalendarDate + 1 <= @endDate
        )
SELECT  CalendarDate,       
        SUM(CASE WHEN ci.Type = 'Invoice' THEN ci.Total ELSE -ci.Total END) / 1.1 
FROM    Calendar
LEFT JOIN
        CustomerInvoice ci
ON      ci.InvoiceDate = CalendarDate
        and ci.IsVoided = 0
GROUP BY
        CalendarDate
OPTION  (MAXRECURSION 0)

答案 1 :(得分:1)

使用所有日期创建名为日历的CTE后,您需要使用 CustomerInvoice 表进行LEFT JOIN。不要忘记在CASE语句中添加额外条件。因为此LEFT JOIN将使用NULL值填充所有不匹配(按日期) ci.type

   SELECT c.CalanderDate AS Date
        , SUM(CASE WHEN ci.Type IS NULL THEN 0
                   WHEN ci.Type = 'Invoice' THEN ci.Total 
                   ELSE - ci.Total END
             ) / 1.1 AS DailyActual
     FROM Calender AS c
LEFT JOIN CustomerInvoice ci ON c.CalanderDate = ci.InvoiceDate
                            AND ci.IsVoided = 0
 GROUP BY c.CalanderDate