2017-10-05 9 views
0

我從來沒有做過像這樣的事情,也沒有能夠找到任何指導,當我谷歌。如何創建基於一個數據行多行根據日期信息創建每行多行

例如,以下是我的數據:

Employee | EmploymentDate 
1   1/1/2017 

每三個月我需要計算的水平。

Employee | EmploymentDate | Level | LevelDateRange 
1   1/1/2017   1  1/1/2017 - 3/31/2017 
1   1/1/2017   2  4/1/2017 - 6/30/2017 
1   1/1/2017   3  7/1/2017 - 9/30/2017 

LevelDateRange計算:

Start Date: If 1st level then EmploymentDate 
      else previous LevelDateRange end date + 1 
End Date: If 1st level then EmployemeentDate + 3 months minus a day 
      else Start date + 3 months 

什麼建議嗎?

+0

是一個新的水平記錄創建每三個月?它存儲在哪裏,因爲它不在你的桌子... – SEarle1986

+0

是每三個月會創建一個新記錄。沒有存儲在任何地方,只是創建一個邏輯選擇語句來完成我上面描述的 – Stephanie

回答

2

在你的情況,你可能會考慮cross apply

select d.employee, v.* 
from mydata d cross apply 
    (values (1, employmentdate, dateadd(day, -1, dateadd(month, 3, d.employmentdate))), 
      (2, dateadd(month, 3, employmentdate), dateadd(day, -1, dateadd(month, 6, d.employmentdate))), 
      (3, dateadd(month, 6, employmentdate), dateadd(day, -1, dateadd(month, 9, d.employmentdate))) 
    ) v(lev, startdate, enddate); 

我會建議你保持在單獨的列的開始日期和結束日期。將它們組合成應用程序級別的字符串或查詢數據庫時。

2

理貨表和CTE:

DECLARE @StartDate DATE 
SELECT @StartDate = EmploymentDate FROM emp 
DECLARE @MonthsSinceStart INT = DATEDIFF(mm,@startDate,GETDATE()) 
DECLARE @NumLevels INT = @MonthsSinceStart/3 

--100 row tally table 
IF OBJECT_ID('tempdb..#Tally') IS NOT NULL DROP TABLE #Tally 
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS Level 
INTO #Tally 
FROM (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) a(n) 
CROSS JOIN (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) b(n); 

WITH cte AS 
(
    SELECT Employee, 
      EmploymentDate, 
      Level, 
      EmploymentDate AS StartDate, 
      DATEADD(dd,-1,DATEADD(mm,3,EmploymentDate)) AS EndDate 
    FROM emp 
      CROSS JOIN #Tally 
    WHERE #Tally.Level =1 
    UNION ALL 
    SELECT Employee, 
      EmploymentDate, 
      Level + 1, 
      DATEADD(dd,1,EndDate) AS StartDate, 
      DATEADD(dd,-1,DATEADD(mm,3,DATEADD(dd,1,EndDate))) AS EndDate 
    FROM cte 
    WHERE cte.Level < @NumLevels 
) 
SELECT Employee, 
     EmploymentDate, 
     Level, 
     CONVERT(NVARCHAR(10),StartDate) + ' - ' + CONVERT(NVARCHAR(10),EndDate) 
FROM cte; 

建議你給它一個測試與一個以上的排在桌子

+0

謝謝!它效果很好。對不起,我的意思是早些時候回覆 – Stephanie

+0

有沒有辦法可以避免CTE?如果您有大量數據,CTE速度很慢 – Stephanie

+0

Gordon Linoff對此問題還有另外一個答案,它不使用CTE。雖然我沒有測試過,但誠實地看來它是一個更好的解決方案! – SEarle1986