Создание календарной таблицы на неделю с использованием сервера SQL - PullRequest
0 голосов
/ 10 июля 2020

Я использую Microsoft SQL Server 2012 и хочу создать следующую таблицу (с 02.12.2018 по 31.08.2019):

Clinic_code Clinic_name        Day_start        Day_end         Weeks_passed
-----------------------------------------------------------------------------
   A123       NAME1           2018-12-02      2018-12-08             1      
   A124       NAME2           2018-12-02      2018-12-08             1      
   A125       NAME3           2018-12-02      2018-12-08             1      
   [...]
   A123       NAME1           2018-12-09      2018-12-15             2 
   A124       NAME2           2018-12-09      2018-12-15             2 
   A125       NAME3           2018-12-09      2018-12-15             2 
   [...]
   A123       NAME1           2018-12-16      2018-12-22             3
   A124       NAME2           2018-12-16      2018-12-22             3
   A125       NAME3           2018-12-16      2018-12-22             3

Я использую следующее code:

DECLARE @fromstartdate date = '2018-12-02'
DECLARE @fromenddate date = '2018-12-08'

SELECT 
    #MyTable.*, B.Day_start, C.Day_end, 
    DATEDIFF(day, MIN(B.Day_start) OVER (), 
    B.Day_start) + 1 AS Weeks_passed
FROM  
    #MyTable
CROSS APPLY 
    (SELECT TOP (DATEDIFF(DAY, @fromstartdate, DATEADD(Month, 9, @fromstartdate))) 
         Day_start = CONVERT(date, DATEADD(DAY, -1 + 7 * ROW_NUMBER() OVER (ORDER BY (SELECT NULL)), @fromstartdate))
     FROM master..spt_values n1) B
CROSS APPLY
    (SELECT TOP (DATEDIFF(DAY, @fromenddate, DATEADD(Month, 9, @fromenddate))) 
         Day_end = CONVERT(date, DATEADD(DAY, -1 + 7 * ROW_NUMBER() OVER (ORDER BY (SELECT NULL)), @fromenddate))
     FROM master..spt_values n1) C

Но я не получаю первые @fromstartdate и @fromenddate, и они выходят далеко за рамки 31 августа 2019 г. Не могли бы вы посоветовать, что я делаю не так?

1 Ответ

0 голосов
/ 10 июля 2020

Я бы выбрал подход создания рекурсивного выражения общей таблицы и присоединил его к вашей таблице. С помощью CTE вы можете создавать список дат и определять диапазоны дат, добавляя 6 дней к каждому началу недели. Прошедшие недели рассчитываются по приращению.

DECLARE @fromstartdate date = '2018-12-02'
DECLARE @fromenddate date = '2019-08-31'

;WITH cteDateList AS
(
    SELECT @fromstartdate AS Day_start, DATEADD(D, 6, @fromstartdate) AS Day_end, 1 AS Weeks_passed
    UNION ALL
    SELECT DATEADD(D, 7, Day_start), DATEADD(D, 6, Day_end), Weeks_passed + 1 FROM cteDateList
    WHERE DATEADD(D, 7, Day_start) <= @fromenddate
)


SELECT mt.clinic_code, mt.clinic_name, dl.* FROM MyTable mt
CROSS APPLY (SELECT * FROM cteDateList) dl
ORDER BY dl.Day_start, mt.clinic_code;
...