#sql #sql-server #tsql
Вопрос:
Я хочу найти всех людей, у которых было по крайней мере 2 разных цвета за последние 3 месяца, а также один уникальный цвет до 3 месяцев.
Определение уникального цвета = у человека должен быть хотя бы один цвет, отличающийся от цвета за последние 3 месяца.
Давайте посмотрим на какой-нибудь пример, чтобы сделать это более понятным:
ID | PersonID | Цвет | Дата |
---|---|---|---|
1 | 1 | «черный» | ‘2021-10-25’ |
2 | 1 | «черный» | ‘2021-09-25’ |
3 | 2 | ‘зеленый’ | ‘2021-09-25’ |
4 | 2 | «йелло» | ‘2021-08-25’ |
5 | 2 | «красный» | ‘2021-07-01’ |
6 | 1 | «черный» | ‘2021-07-01’ |
Исключенный вывод:
PersonID |
---|
2 |
Поскольку PersonID = 2, у него есть «уникальный цвет» = (красный цвет, до 3 месяцев, и он не появлялся за последние 3 месяца. А также у него было как минимум 2 цвета за последние 3 месяца (зеленый и желтый)
Спасибо.
Комментарии:
1. Я просто приведу вам пример, чтобы вы начали
SELECT * FROM Tbl WHERE Date Between (@3MonthsAgo, @2MonthsAgo) AND Id IN (SELECT Id FROM Tbl GROUP BY Id, Color WHERE Date Between (@2MonthsAgo, GetDate()) AND Count(Color) > 1)
2. Пожалуйста, предоставьте достаточно кода, чтобы другие могли лучше понять или воспроизвести проблему.
3. Откуда берется PersonID 3, его нет в образце данных
4. Я отредактировал свой пост. Извините за путаницу.
Ответ №1:
Вы можете использовать оконные функции в сочетании с условной агрегацией
SELECT PersonID
FROM (
SELECT *,
rn = ROW_NUMBER() OVER (PARTITION BY PersonID, Color ORDER BY Date DESC),
PrevColor = LAG(Color) OVER (PARTITION BY PersonID ORDER BY Date DESC)
FROM Color c
) c
GROUP BY PersonID
HAVING COUNT(CASE WHEN Date < DATEADD(month, -3, GETDATE()) AND rn = 1 THEN 1 END) > 0
AND COUNT(CASE WHEN Date >= DATEADD(month, -3, GETDATE()) AND PrevColor <> Color THEN 1 END) > 0;