T- SQL список лет и месяцев между двумя датами - PullRequest
0 голосов
/ 10 февраля 2020

У меня есть таблица со списком лиц, у которых есть дата вступления в силу и дата расторжения. Пример Person 1, 20171201, 20180601 Для каждой записи мне нужно вывести список лет и месяцев, когда они были «активными» между двумя датами. Таким образом, вывод будет выглядеть как

Вывод данных

Это в SQL Server 2016 Любая помощь будет оценена!

Ответы [ 3 ]

1 голос
/ 10 февраля 2020

Только потому, что я не видел, чтобы это предлагалось Вот еще один подход, который использует ad-ho c календарную таблицу

Обратите внимание на базовую дату 2000-01-01 и 10000 дней ... расширьте или сожмите при необходимости

Пример

Declare @YourTable table (Person int,startdate date,  enddate date)
Insert Into @YourTable values 
(1,'20171201','20180601')

Select Distinct 
       A.Person
      ,ActiveYear = year(D)
      ,ActiveMonth = month(D)
From  @YourTable A
Join  (
          Select Top 10000 D=DateAdd(DAY,-1+Row_Number() Over (Order By (Select Null)),'2000-01-01') 
                From  master..spt_values n1,master..spt_values n2
      ) B on D between startdate and enddate

Возвращает

Person  ActiveYear  ActiveMonth
1       2017        12
1       2018        1
1       2018        2
1       2018        3
1       2018        4
1       2018        5
1       2018        6
0 голосов
/ 10 февраля 2020

Добро пожаловать в stackoverflow! Для лучшей помощи полезно включить образцы легко используемых данных DDL, которые мы можем использовать для быстрого воссоздания того, что вы делаете, и предоставления решения. Обратите внимание на этот пример данных:

DECLARE @yourtable TABLE(person VARCHAR(20), date1 DATE, date2 DATE)
INSERT @yourtable (person, date1, date2) 
VALUES ('Person1','20171201', '20180601'), ('Person2','20171001', '20180101'),
       ('Person3','20180101', '20180301');

SELECT t.* FROM @yourtable AS t;

Возвращает:

person               date1      date2
-------------------- ---------- ----------
Person1              2017-12-01 2018-06-01
Person2              2017-10-01 2018-01-01
Person3              2018-01-01 2018-03-01

(я добавил пару строк). Вот мое решение:

DECLARE @yourtable TABLE(person VARCHAR(20), date1 DATE, date2 DATE)
INSERT @yourtable (person, date1, date2) 
VALUES ('Person1','20171201', '20180601'), ('Person2','20171001', '20180101'),
       ('Person3','20180101', '20180301');

SELECT 
  Person      = t.person,
    ActiveYear  = YEAR(st.DT),
  ActiveMonth = MONTH(st.Dt)
FROM   @yourtable AS t
CROSS APPLY
(
  SELECT TOP (DATEDIFF(MONTH,t.date1,t.date2)) ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
  FROM       (VALUES(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) AS a(x)
  CROSS JOIN (VALUES(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) AS b(x)
) AS iTally(N)
CROSS APPLY (VALUES(DATEADD(MONTH, iTally.N-1, t.date1))) AS st(Dt);

Что возвращает:

Person               ActiveYear  ActiveMonth
-------------------- ----------- -----------
Person1              2017        12
Person1              2018        1
Person1              2018        2
Person1              2018        3
Person1              2018        4
Person1              2018        5
Person2              2017        10
Person2              2017        11
Person2              2017        12
Person3              2018        1
Person3              2018        2

Дайте мне знать, если у вас есть вопросы.

0 голосов
/ 10 февраля 2020

На основании предоставленной вами информации я немного угадал. Возможно, рекурсивный CTE поможет:

DECLARE @tab TABLE (Person INT, EffectiveDate DATE, TerminationDate DATE)
INSERT @tab VALUES
(1, '2017-12-01', '2018-05-31'),
(2, '2017-10-01', '2018-01-01'),
(3, '2018-02-01', '2018-12-01')

;WITH t AS (
    SELECT Person, EffectiveDate AS Dt
    FROM @tab
    UNION ALL
    SELECT Person, DATEADD(mm,1,Dt)
    FROM t
    WHERE t.Dt < (SELECT DATEADD(mm,-1,TerminationDate) FROM @tab tt WHERE tt.Person = t.Person)
    )

SELECT *
FROM t
ORDER BY Dt

Тогда возьмите DATEPART()

SELECT t.Person
     , t.Dt
     , DATEPART(yyyy, t.Dt) ActiveYear
     , DATEPART(mm, t.Dt) ActiveMonth
FROM t
ORDER BY Dt
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...