Найти всех пользователей с определенными условиями

#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;
 

db<>скрипка