如何构建一个包含分隔日期的表?

时间:2015-10-14 12:39:25

标签: sql-server tsql common-table-expression

你能解决我的问题吗?

我正在使用MS SQL Server 2008,我有一个包含许多员工的庞大桌子。 在此表中,我有关于"收入","合同开始的数据"和#34;合同结束"。 所以我想要建立的是:我想得到一个结果集,其中员工为公司工作的时间分为几周,以及他每周在平均收入中赚多少钱。每周应从合同开始的那一天开始#34;最后一行应该是一周的最后一天,以"合同结束"结束。

例如:

Employee Number | StartDate | EndDate | Salary 4711 20150101 20150124 4000

Employee Number | Weeks | AVG Salary (weeks) row1: 4711 20150101 800 row2: 4711 20150108 800 row3: 4711 20150115 800 row4: 4711 20150122 800 row5: 4711 20150124 800

请注意,第5行以20150124结束,而不是在一周的最后一天。

所以我的代码到现在为止。但它还没有完成,我不知道如何在上面提到的逻辑中构建周数:

  DECLARE @tbl AS TABLE
    (
      ID VARCHAR(50) ,
     Earning FLOAT,
      StartDate DATE ,
     EndDate DATE
    )INSERT  INTO @tbl
        ( ID, Earning, StartDate, EndDate
    SELECT  employee_ID  AS ID   
    ,([Total Earning]/ (SELECT datediff(WEEK,[EndDate],
    [StartDate])+1
    FROM [employee_table] WHERE employee_ID = 'EKA-0004562'))
    ,[StarTDate]
    ,[EndDate]
    FROM [employee_table]
    WHERE  employee_ID = 'EKA-0004562'
    ;
    WITH    cte
              AS ( SELECT   T.ID ,
                        T.Earning ,
                        T.StartDate ,
                        T.EndDatum ,
                        CONVERT(DATE, NULL) AS Dt ,
                        n = 0
               FROM     @tbl AS T
               UNION ALL
               SELECT   cte.ID ,
                        cte.Earning ,
                        cte.StartDate ,
                        cte.EndDatum ,
                        DATEADD(WEEK, n, cte.StartDate) ,
                        cte.n + 1
               FROM     cte
               WHERE    n <= DATEDIFF(WEEK, cte.StartDate, cte.EndDatum)
             )
    SELECT  cte.ID ,
            cte.Earning,
            dt AS WEEKS
    FROM    cte
    WHERE   cte.Dt IS NOT NULL

你能给我一个如何构建它的建议吗?

1 个答案:

答案 0 :(得分:1)

这样可行。

  • 我首先创建虚拟数据:

    Declare @data table(Employee_Number int, StartDate datetime, EndDate datetime, Salary bigint)
    Insert into @data(Employee_Number, StartDate, EndDate, Salary) values
        (4711, '20150101', '20150124', 4000)
        , (4712, '20150101', '20150201', 4000);
    ;
    

请注意,我添加了第二行。它可以使用任意数量的行。

  • 主要查询

    with inc(n) as(
        Select 7*(ROW_NUMBER() over(order by (select 1)) -1)
        From (
            Select 1 From (values (1), (1), (1), (1), (1), (1), (1), (1), (1), (1)) as x1(n)
            Cross Join (values (1), (1), (1), (1), (1), (1), (1), (1), (1), (1)) as x2(n)
        ) x(n)
    )
    Select Employee_Number
        , Weeks = case when DATEADD(DAY, i.n, StartDate) <= EndDate then DATEADD(DAY, i.n, StartDate) else EndDate end
        , Avg = Salary/(CEILING(CAST(DATEDIFF(DAY, StartDate, EndDate) as numeric(9,1))/7)+1)
    From @data d
    Inner Join inc i on i.n < ((DATEDIFF(DAY, StartDate, EndDate)))+7
    Order By Employee_Number, Weeks
    

Inc创建一个从0到700(7 * 100)的连续数字列表,该列表将添加到StartDate。如果您需要超过7 * 100的范围,请添加x3(<7 * 1.000),x4(&lt; 7 * 10.000)等等。

  • 输出:

    Employee_Number Weeks                       Average
    4711            2015-01-01 00:00:00.000     800
    4711            2015-01-08 00:00:00.000     800
    4711            2015-01-15 00:00:00.000     800
    4711            2015-01-22 00:00:00.000     800
    4711            2015-01-24 00:00:00.000     800
    4712            2015-01-01 00:00:00.000     666
    4712            2015-01-08 00:00:00.000     666
    4712            2015-01-15 00:00:00.000     666
    4712            2015-01-22 00:00:00.000     666
    4712            2015-01-29 00:00:00.000     666
    4712            2015-02-01 00:00:00.000     666