SQL Server 2008:创建没有的数据?

时间:2015-04-15 10:33:22

标签: sql-server sql-server-2008

我正在努力创建没有数据的数据,我有一个返回类似数据的查询:

enter image description here

此表显示,对于客户123,我们仅在6月,7月和12月付款。

查询中唯一值得注意的项目是打开月份与DATEDIFF之间的MonthPayment(这会得到mnth列。)

现在我摔倒了,我需要创建上面的列,但是对于已经过去的所有月份,无论如下

enter image description here

忽略无薪月份的月付款字段,这不应该返回任何内容!

1 个答案:

答案 0 :(得分:1)

您需要做的是将此表连接到您可能需要的所有值的列表,如Zohar Peled指出的问题。您的情况稍微复杂一些,因为您可能需要一次返回多个客户端,并且只希望查看与该客户端的开始和结束范围相关的数据。我已经改编了我前一段时间发布的a similar answer代码,它应该会告诉你这是怎么做的。

-- set up some sample data
    DECLARE @MyTable TABLE
      (
        ClientNo INT,
        Collected NUMERIC(5,2),
        MonthPayment DATETIME,
        MonthOpened DATETIME,
        CurrentMonth DATETIME
      )

    INSERT INTO @MyTable 
      (
        ClientNo,
        Collected,
        MonthPayment,
        MonthOpened,
        CurrentMonth
      ) -- note: I'm in the US, so I'm using the US equivalent of the months you asked for
    SELECT 123, 147.25, '7/1/2014', '12/1/2013', '4/1/2015' 
    UNION
    SELECT 123, 40, '12/1/2014', '12/1/2013', '4/1/2015' 
    UNION
    SELECT 123, 50, '6/1/2014', '12/1/2013', '4/1/2015' 

-- create a recursive CTE that contains a list of all months that you could wish to see
    --define start and end limits
        Declare @todate datetime, @fromdate datetime
        Select @fromdate=(SELECT MIN(MonthOpened) FROM @MyTable), @todate=DATEADD(MONTH, 1, GETDATE())
    -- define CTE
    ;With DateSequence( DateValue ) as
    (
        Select @fromdate as DateValue
            union all
        Select dateadd(MONTH, 1, DateValue)
            from DateSequence
            where DateValue < @todate
    )

--select result
    SELECT 
        ClientStartEnd.ClientNo,
        ISNULL(MyTable.Collected, 0.00) AS Collected,
        DateSequence.DateValue AS MonthPayment,
        ClientStartEnd.MonthOpened,
        DATEDIFF(MONTH, ClientStartEnd.MonthOpened, DateSequence.DateValue) + 1 AS Mnth,
        ClientStartEnd.CurrentMonth
    FROM 
        DateSequence 
         INNER JOIN 
          (
            SELECT DISTINCT 
                ClientNo, 
                MonthOpened, 
                CurrentMonth
            FROM @MyTable 
          ) ClientStartEnd ON 
            DateSequence.DateValue BETWEEN 
                ClientStartEnd.MonthOpened AND 
                ClientStartEnd.CurrentMonth
         LEFT JOIN 
        @MyTable MyTable ON 
            ClientStartEnd.ClientNo = MyTable.ClientNo AND
            DateSequence.DateValue = MyTable.MonthPayment 
    OPTION (MaxRecursion 0)