T SQL - Посчитать людей с посещениями за 3 месяца подряд - PullRequest
0 голосов
/ 05 октября 2018

Со следующими данными:

Declare @t Table 
(
Name        Varchar(1),
VisitDate   Date
)

Insert Into @t select 'A','2017-01-05'
Insert Into @t select 'A','2017-03-05'
Insert Into @t select 'A','2017-04-05'
Insert Into @t select 'A','2017-05-05'
Insert Into @t select 'A','2017-08-05'
Insert Into @t select 'B','2017-03-05'
Insert Into @t select 'C','2017-01-05'
Insert Into @t select 'C','2017-02-05'
Insert Into @t select 'C','2017-04-05'
Insert Into @t select 'D','2017-01-05'
Insert Into @t select 'D','2017-02-05'
Insert Into @t select 'D','2017-03-05'
Insert Into @t select 'D','2017-06-05'
Insert Into @t select 'B','2018-01-05'
Insert Into @t select 'B','2018-02-05'
Insert Into @t select 'B','2018-03-05'
Insert Into @t select 'E','2018-01-05'
Insert Into @t select 'E','2018-02-05'
Insert Into @t select 'E','2018-03-05'
Insert Into @t select 'E','2018-06-05'

Мне нужно написать запрос, который будет возвращать год и имена, которые имеют VisitDates, в любых трех последовательных месяцах любого года.

На основеданные, которые я ожидаю увидеть:

2017 A
2017 D
2018 B
2018 E

Если честно, я не знаю, с чего начать с использованием SQL.

Буду признателен за любую помощь, которую смогу получить.

Спасибо !!

Ответы [ 2 ]

0 голосов
/ 05 октября 2018

Вы можете избежать объединений или анализа всего набора данных несколько раз, используя тот же метод, что и в gaps-and-islands.

http://rextester.com/SYHJ40676

WITH
  sequenced AS
(
  SELECT
    Name,
    YEAR(VisitDate)         AS VisitYear,
    MONTH(VisitDate)        AS VisitMonth,
    ROW_NUMBER()
      OVER (PARTITION BY Name, YEAR(VisitDate)
                ORDER BY MONTH(VisitDate)
           )
                            AS MonthSequenceID
  FROM
    @t
  GROUP BY
    Name,
    YEAR(VisitDate),
    MONTH(VisitDate)
)
SELECT DISTINCT
  Name,
  VisitYear
FROM
  sequenced
GROUP BY
  Name,
  VisitYear,
  VisitMonth - MonthSequenceID
HAVING
  COUNT(*) >= 3
0 голосов
/ 05 октября 2018

просто присоедините два следующих месяца к данным и посмотрите, куда они идут:

SELECT DATEPART(year, m1.VisitDate), m1.Name
FROM @t m1
  JOIN @t m2 on m2.Name = m1.Name AND DATEPART(month, m2.VisitDate) = DATEPART(month, m1.VisitDate) + 1
  JOIN @t m3 on m3.Name = m1.Name AND DATEPART(month, m3.VisitDate) = DATEPART(month, m1.VisitDate) + 2

, поскольку в комментарии был задан вопрос, как решить эту проблему с перекрытием на год, это должно работать:

SELECT DATEPART(year, m1.VisitDate), m1.Name
FROM @t m1
  JOIN @t m2 on m2.Name = m1.Name AND EOMONTH(m1.VisitDate,1) = EOMONTH(m2.VisitDate)
  JOIN @t m3 on m3.Name = m1.Name AND EOMONTH(m1.VisitDate,2) = EOMONTH(m3.VisitDate)

документ по EOMONTH: https://docs.microsoft.com/en-us/sql/t-sql/functions/eomonth-transact-sql?view=sql-server-2017

edit: мой ответ - просто быстрый взлом и крайне неэффективный и содержит ошибки, когда в месяце несколько экземпляров.Я предлагаю использовать этот ответ: https://stackoverflow.com/a/52669713/4903754

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...