Мне нужно написать запрос, который показывает результат с разбивкой на FormID
, которые имеют значение больше 5 на основе самого последнего LogDate
.
Основываясь на самом последнем LogDate
, если было значение меньше 5, оно должно отображать значения с этой точки, которые больше 5, поскольку значения под 5 являются «сбросом», если хотите.
Я в основном смотрю на недавние последовательные записи LogDate
, которые больше 5.
Допустим, у нас есть следующий набор рекордов:
FormID Value LogDate
--------------------------
Form2 6 10/12/19
Form2 7 10/13/19
Form1 8 10/12/19
Form1 12 10/12/19
Form1 3 10/14/19
Form1 8 10/15/19
Form1 6 10/21/19
Следующее вернет следующее (обратите внимание, что я также хотел бы показать row_num:
FormID Value LogDate row_num
----------------------------------
Form2 6 10/12/19 1
Form2 7 10/13/19 2
Form1 8 10/15/19 1
Form1 6 10/21/19 2
Обратите внимание, что в приведенном выше примере, поскольку следующая запись имела недавнее значение меньше 5 (значение 3), нам нужно получить записи, которые больше 5.
Другой пример:
FormID Value LogDate
Form1 8 10/15/19
Form1 3 10/21/19
РЕЗУЛЬТАТ: Результаты не будут отображаться, так как в последней записи больше 5
Другой пример:
FormID Value LogDate
Form2 4 10/12/19
Form2 3 10/13/19
Form1 16 10/12/19
Form1 3 10/12/19
Form1 3 10/14/19
Form1 8 10/15/19
Form1 12 10/21/19
Результат здесь будет:
FormID Value LogDate row_num
Form1 8 10/15/19 1
Form1 12 10/21/19 2
Другой пример:
FormID Value LogDate
Form1 12 10/12/19
Form2 13 10/13/19
Результат:
FormID Value LogDate row_num
Form1 12 10/12/19 1
Form2 13 10/13/19 2
Насколько я понимаю, это можно сделать с помощью функции LAG, но я не знаю, как это сделать в целом.
Мы можем сделать что-то вроде следующего:
DECLARE @mytable TABLE
(
FormID VARCHAR(50),
[Value] INT,
LogDate DATETIME
)
select t.*,
lag(value) over(partition by formid order by logdate) lag_value
from @mytablet
Но не знаю, как все это собрать воедино.
3 ответа
Если я правильно вас понял, вы можете сделать это с помощью таких оконных функций:
select
from (
select t.*,
row_number() over(partition by formid order by logdate desc) rn,
sum(case when value > 5 then 1 else 0 end) over(partition by formid order by logdate desc) grp
from mytable t
) t
where rn = grp
Идея состоит в том, чтобы сравнить количество значений выше 5
с номером строки, считая от самого последнего значения. Строки, в которых два значения равны, можно сохранить.
Найдите ориентировочный ответ в скрипке.
reset_calendar
- это даты, когда произошел сброс, который используется для фильтрации данных.
SELECT temp.*,
ROW_NUMBER() OVER (PARTITION BY temp.FormID ORDER BY temp.LogDate) AS Sequence
FROM (
SELECT t.*
FROM t
LEFT JOIN (
SELECT FormID, MAX(LogDate) AS recent_reset
FROM t
WHERE Value<6
GROUP BY FormID) AS reset_calendar
ON t.FormID = reset_calendar.FormID
WHERE t.LogDate > reset_calendar.recent_reset OR reset_calendar.recent_reset IS NULL)temp
Один из методов:
select t.*,
row_number() over (partition by formid order by logdate)
from t
where t.logdate > (select coalesce(max(t.logdate), '2000-01-01')
from t t2
where t2.formid = t.formid and t.value <= 5
);
Вы также можете использовать оконные функции:
select t.*,
row_number() over (partition by formid order by logdate)
from (select t.*,
max(case when value <= 5 then logdate end) over (partition by formid) as logdate_5
from t
) t
where logdate_5 is null or
date > logdate_5
order by formid, logdate;
Похожие вопросы
Связанные вопросы
Новые вопросы
sql
Язык структурированных запросов (SQL) - это язык запросов к базам данных. Вопросы должны включать примеры кода, структуру таблицы, примеры данных и тег для используемой реализации СУБД (например, MySQL, PostgreSQL, Oracle, MS SQL Server, IBM DB2 и т. Д.). Если ваш вопрос относится исключительно к конкретной СУБД (использует определенные расширения / функции), используйте вместо этого тег этой СУБД. Ответы на вопросы, помеченные SQL, должны использовать стандарт ISO / IEC SQL.