Вопрос или проблема
Сценарий
Требование.
выбрать все правила, которые неактивны (Rule_table.Status), соответствующие самой последней записи аудита с audit_text=”status_change”, где дата создания прошла 6 месяцев.
В приведенном выше примере есть 2 записи аудита, которые неактивны, и запрос НЕ ДОЛЖЕН выбирать Rule_id 4, так как его последняя запись аудита с audit_text ‘Status_Change’ всего лишь месяц назад.
Ниже приведен SQL, который я попробовал (Microsoft SQL server- TSQL)
select R.Id, A.created_date from Rule R
join Rule_Audit A on R.id=A.id
where R.ID= (
select top1 1 ID from Rule_Audit where Rule_Id=R.Rule_Id and created_date < dateadd
(MONTH, -7, GETDATE()) order by created_date desc
)
and R.status="Inactive"
Но этот запрос дает результат Rule id 4, так как приведенный выше запрос соответствует его записи аудита 100. Может кто-то помочь мне с правильным запросом
Разбирая ваш запрос
выбрать все правила, которые неактивны (Rule_table.Status), соответствующие самой последней записи аудита с audit_text=”status_change”, где дата создания прошла 6 месяцев.
У него 3 части
- Выберите все правила, которые неактивны
- Но только те, для которых последняя запись аудита имеет audit_text=”status_change” и прошло 6 месяцев с момента этого события status_change.
Вот правильный запрос,
WITH MostRecentAudit AS (
SELECT
Rule_Id,
MAX(created_date) AS LastAuditDate
FROM Rule_Audit
WHERE Audit_Text="Status_Change"
GROUP BY Rule_Id
)
SELECT R.Rule_Id, R.Status, A.LastAuditDate
FROM Rule R
JOIN MostRecentAudit A ON R.Rule_Id = A.Rule_Id
WHERE R.Status="Inactive"
AND A.LastAuditDate < DATEADD(MONTH, -6, GETDATE());
Вам следует добавить некоторые тестовые данные в текстовом формате, но что-то вроде этого может помочь:
SELECT R.Id, x.created_date
FROM [RULE] R
CROSS APPLY (
SELECT TOP 1 A.*
FROM Rule_Audit A
WHERE A.id = R.id
AND A.audit_text="status_change"
ORDER BY A.created_date DESC
) x
WHERE x.created_date < dateadd(MONTH, -7, GETDATE())
AND R.status="Inactive"
Ответ или решение
Запрос подзапроса для соответствия самой последней записи дочерней таблицы
В этой задаче мы хотим написать SQL-запрос для получения всех правил с неактивным статусом из таблицы Rule
, и при этом учитывать только те аудиты, которые соответствуют последней записи с текстом "status_change" и были созданы более шести месяцев назад. Это важный критерий, так как мы не хотим включать в выборку записи, у которых соответствующие аудиты были созданы недавно.
Структура задачи
-
Выбор неактивных правил: Мы должны сначала отобрать записи из таблицы
Rule
, у которых статус "Inactive". -
Поиск последних записей аудита: Нам нужно найти для каждого правила самую последнюю запись аудита, где текст аудита равен "status_change".
-
Проверка временного условия: Мы должны убедиться, что дата создания этой аудит записи старше шести месяцев от текущей даты.
SQL-запрос
Ниже представлен SQL-запрос, который соответствует указанным требованиям:
WITH MostRecentAudit AS (
SELECT
Rule_Id,
MAX(created_date) AS LastAuditDate
FROM Rule_Audit
WHERE Audit_Text = 'status_change'
GROUP BY Rule_Id
)
SELECT R.Rule_Id, R.Status, A.LastAuditDate
FROM Rule R
JOIN MostRecentAudit A ON R.Rule_Id = A.Rule_Id
WHERE R.Status = 'Inactive'
AND A.LastAuditDate < DATEADD(MONTH, -6, GETDATE());
Объяснение запроса
-
CTE (Common Table Expression)
MostRecentAudit
:- Мы собираем все записи из таблицы
Rule_Audit
, отбираем только те, где текст аудита равен "status_change". - Используем
MAX(created_date)
, чтобы получить дату последнего аудита по каждомуRule_Id
. - Группируем результаты по
Rule_Id
, чтобы каждая строка содержала самую последнюю дату аудита для соответствующего правила.
- Мы собираем все записи из таблицы
-
Основной запрос:
- Мы выбираем все поля из таблицы
Rule
и присоединяем результат из CTEMostRecentAudit
поRule_Id
. - Условие
WHERE
фильтрует неактивные правила и проверяет, чтобы последняя дата аудита была более шести месяцев назад, используя функциюDATEADD
.
- Мы выбираем все поля из таблицы
Альтернативный подход с использованием CROSS APPLY
Еще один вариант запроса, который также решает задачу, — использовать CROSS APPLY
для получения последней записи аудита непосредственно для каждого правила:
SELECT R.Rule_Id, x.created_date
FROM Rule R
CROSS APPLY (
SELECT TOP 1 A.*
FROM Rule_Audit A
WHERE A.Rule_Id = R.Rule_Id
AND A.Audit_Text = 'status_change'
ORDER BY A.created_date DESC
) x
WHERE x.created_date < DATEADD(MONTH, -6, GETDATE())
AND R.Status = 'Inactive';
Заключение
В результате выполнения любого из этих запросов вы получите список правил с неактивным статусом, где последние записи аудита, относящиеся к изменению статуса, были созданы более чем шесть месяцев назад. Это помогает обеспечить актуальность статуса и избегает ошибок, связанных с недавними изменениями. Важно помнить, что поддержание высокой степени актуальности данных является критически важным аспектом для надежного функционирования систем управления данными.