#sql #oracle #oracle12c
Вопрос:
У меня есть таблица, из которой я пытаюсь извлечь информацию с помощью функции ЗАДЕРЖКИ.
Тип | Дата | Ценность |
---|---|---|
A | 01 | 1 |
A | 02 | 2 |
B | 01 | 3 |
Я пытаюсь получить строки по типу со значением за этот месяц и за месяц до этого, так что в идеале:
Тип | Дата | Значение M | Значение M-1 |
---|---|---|---|
A | 02 | 2 | 1 |
B | 02 | 0 | 3 |
SELECT
Type,
Date,
Value as Value M,
LAG (Value,1,0) over(PARTITION BY Type ORDER BY Date) as Value M-1
FROM Table
За исключением того, конечно, что, поскольку нет строки для типа B и месяца 02, я не получаю строку для типа B.
У вас есть какие-нибудь предложения?
Комментарии:
1. Я не понимаю. Ваш запрос не фильтруется, но ваши результаты содержат только две строки, а не три.
2. Если
Date
это столбец типа данныхdate
, то в примерах показывайте даты, а не строки типа01
и02
. (Это строки, а не числа; есть число «1», «01» — это не число.) Мы ответим на ваш вопрос в том виде, в каком он был опубликован, а затем вы вернетесь и измените вопрос, потому что решение работает для целых чисел или строк, но вы не можете напрямую перевести его в даты. Отдельно от этого: решение, скорее всего, будет основано на секционированном внешнем соединении и не будет иметь ничего общего с ЛАГОМ или какой-либо другой аналитической функцией. Не делайте свою попытку ответить частью вопроса.3. @GordonLinoff Да, хорошо пойман, в моем результате должно было быть 3 строки.
4. @mathguy На самом деле мой столбец даты представляет собой строку в формате «YYYYMM». В итоге я использовал ЛАГ: хитрость заключалась в том, чтобы восстановить всю таблицу без пропущенных строк.
Ответ №1:
Простая задержка, вероятно, не поможет, потому что вам нужно создать запись за последний месяц, если она не существует для данного типа. Если ваша дата хранится в виде целого числа, как в образцах данных, следует учитывать подобный шаблон. Если он хранится как дата, вам нужно будет добавить какой — то рейтинг в соединение или извлечение(месяц с даты) — 1 (будьте осторожны с январем), но это должно дать представление о сути.
WITH TYPE_LATEST_MONTH AS
( SELECT DISTINCT
TYPE,
(SELECT MAX(DATE) FROM TABLE) AS LATEST_MONTH
FROM TABLE
)
SELECT TLM.TYPE,
TLM.LATEST_MONTH AS DATE,
COALESCE(TLM.VALUE_M, 0) AS VALUE_M,
COALESCE(TLM_PREV.VALUE_M, 0) AS VALUE_M_MINUS_1
FROM TYPE_LATEST_MONTH TLM
LEFT
JOIN TABLE TBL
ON TLM.Type = TBL.Type
AND TLM.LATEST_MONTH = TBL.DATE
LEFT
JOIN TABLE TBL_PREV
ON TLM.Type = TBL_PREV.Type
AND TLM.LATEST_MONTH = TBL_PREV.DATE - 1
Комментарии:
1. Спасибо вам за ваш ответ! К сожалению, я не мог использовать его оптом, потому что, если присмотреться к нему повнимательнее, таблица усечена на предыдущем шаге, и поэтому мне нужно снова сгенерировать всю историю, но это натолкнуло меня на мысль, что мне нужно это сделать. В своем запросе я делаю перекрестное соединение для разных дат и разных типов, слева соединяю это с таблицей, чтобы получить значения, а затем выполняю задержку в результате. Мне удалось непреднамеренно исправить ошибку в процессе, так что все хорошо 😀