Я хотел бы получить помощь, чтобы получить конкретный результат с Oracle 11gR2.Строки в столбцы с функцией LEAD/LAG
Прежде всего, мне нужно начать с таблицей «RAW_DATA» расположены так:
CREATE TABLE RAW_DATA
AS
SELECT 'MTL' AS EMH_CED,'ATW 25-55' AS EMH_ID,to_date('2014-12-03 17:17:10','yyyy-mm-dd hh24:mi:ss') AS EMH_DATE_HEURE,'AM' AS EMH_TYPE_MESURE,'A' AS EMH_PHASE,75 AS EMH_MESURE FROM dual union ALL
SELECT 'MTL','ATW 25-55',to_date('2014-12-03 17:17:10','yyyy-mm-dd hh24:mi:ss'),'AM','B',100 FROM dual union ALL
SELECT 'MTL','ATW 25-55',to_date('2014-12-03 17:17:10','yyyy-mm-dd hh24:mi:ss'),'AM','C',98 FROM dual union ALL
SELECT 'MTL','ATW 25-55',to_date('2014-12-03 17:17:29','yyyy-mm-dd hh24:mi:ss'),'AM','A',75 FROM dual union ALL
SELECT 'MTL','ATW 25-55',to_date('2014-12-03 17:17:29','yyyy-mm-dd hh24:mi:ss'),'AM','B',100 FROM dual union ALL
SELECT 'MTL','ATW 25-55',to_date('2014-12-03 17:17:29','yyyy-mm-dd hh24:mi:ss'),'AM','C',98 FROM dual union ALL
SELECT 'MTL','ATW 25-55',to_date('2014-12-03 17:17:57','yyyy-mm-dd hh24:mi:ss'),'AM','A',84 FROM dual union ALL
SELECT 'MTL','ATW 25-55',to_date('2014-12-03 17:17:57','yyyy-mm-dd hh24:mi:ss'),'AM','B',100 FROM dual union ALL
SELECT 'MTL','ATW 25-55',to_date('2014-12-03 17:17:57','yyyy-mm-dd hh24:mi:ss'),'AM','C',98 FROM dual union ALL
SELECT 'MTL','ATW 25-55',to_date('2014-12-04 00:00:00','yyyy-mm-dd hh24:mi:ss'),'AM','B',91 FROM dual union ALL
SELECT 'MTL','ATW 25-55',to_date('2014-12-04 00:00:00','yyyy-mm-dd hh24:mi:ss'),'AM','C',89 FROM dual union ALL
SELECT 'MTL','ATW 25-55',to_date('2014-12-04 15:06:07','yyyy-mm-dd hh24:mi:ss'),'AM','A',0 FROM dual union ALL
SELECT 'MTL','ATW 25-55',to_date('2014-12-04 15:06:07','yyyy-mm-dd hh24:mi:ss'),'AM','B',0 FROM dual union ALL
SELECT 'MTL','ATW 25-55',to_date('2014-12-04 15:06:07','yyyy-mm-dd hh24:mi:ss'),'AM','C',0 FROM dual union ALL
SELECT 'MTL','ATW 25-55',to_date('2014-12-04 16:22:37','yyyy-mm-dd hh24:mi:ss'),'AM','A',23 FROM dual union ALL
SELECT 'MTL','ATW 25-55',to_date('2014-12-04 16:22:37','yyyy-mm-dd hh24:mi:ss'),'AM','B',24 FROM dual union ALL
SELECT 'MTL','ATW 25-55',to_date('2014-12-04 16:22:37','yyyy-mm-dd hh24:mi:ss'),'AM','C',24 FROM dual union ALL
SELECT 'MTL','ATW 25-55',to_date('2014-12-04 16:27:36','yyyy-mm-dd hh24:mi:ss'),'AM','A',34 FROM dual union ALL
SELECT 'MTL','ATW 25-55',to_date('2014-12-04 16:27:43','yyyy-mm-dd hh24:mi:ss'),'AM','B',40 FROM dual union ALL
SELECT 'MTL','ATW 25-55',to_date('2014-12-04 16:27:43','yyyy-mm-dd hh24:mi:ss'),'AM','C',39 FROM dual union ALL
SELECT 'MTL','ATW 25-55',to_date('2014-12-04 16:28:12','yyyy-mm-dd hh24:mi:ss'),'AM','A',51 FROM dual union ALL
SELECT 'MTL','ATW 25-55',to_date('2014-12-04 16:28:12','yyyy-mm-dd hh24:mi:ss'),'AM','B',58 FROM dual union ALL
SELECT 'MTL','ATW 25-55',to_date('2014-12-04 16:28:12','yyyy-mm-dd hh24:mi:ss'),'AM','C',57 FROM dual union ALL
SELECT 'MTL','ATW 25-55',to_date('2014-12-04 16:40:33','yyyy-mm-dd hh24:mi:ss'),'AM','B',80 FROM dual union ALL
SELECT 'MTL','ATW 25-55',to_date('2014-12-04 16:40:33','yyyy-mm-dd hh24:mi:ss'),'AM','C',78 FROM dual union ALL
SELECT 'MTL','ATW 25-55',to_date('2014-12-04 16:41:02','yyyy-mm-dd hh24:mi:ss'),'AM','A',73 FROM dual union ALL
SELECT 'MTL','ATW 25-55',to_date('2014-12-04 16:47:10','yyyy-mm-dd hh24:mi:ss'),'AM','A',83 FROM dual union ALL
SELECT 'MTL','ATW 25-55',to_date('2014-12-04 16:55:39','yyyy-mm-dd hh24:mi:ss'),'AM','B',98 FROM dual union ALL
SELECT 'MTL','ATW 25-55',to_date('2014-12-04 16:27:59','yyyy-mm-dd hh24:mi:ss'),'AM','A',0 FROM dual union ALL
SELECT 'MTL','ATW 25-55',to_date('2014-12-04 16:27:59','yyyy-mm-dd hh24:mi:ss'),'AM','B',0 FROM dual union ALL
SELECT 'MTL','ATW 25-55',to_date('2014-12-04 16:27:59','yyyy-mm-dd hh24:mi:ss'),'AM','C',0 FROM dual union ALL
SELECT 'MTL','ATW 25-55',to_date('2014-12-04 16:56:37','yyyy-mm-dd hh24:mi:ss'),'AM','C',96 FROM dual;
Окончательный результат я ищу заключается в следующем:
мне нужно иметь, на для каждого значения «EMH_PHASE» («A», «B» и «C»). Этот результат необходимо сохранить в трех новых столбцах, которые называются «MESURE_A», «MESURE_B» и «MESURE_C».
После этого мне нужен datarow непосредственно перед и после пересечения нуля (это когда MESURE_A=MESURE_B=MESURE_C=0
, с «RAW_DATA», отсортированным по «EMH_DATE_HEURE»). Мне также нужен datarow, соответствующий пересечениям нуля. В моем контексте может быть несколько пересечений с нуля. Затем, на основе таблицы «RAW_DATA», результат я хочу получить следующий:
EMH_CED, EMH_ID, EMH_DATE_HEURE, EMH_TYPE_MESURE, MESURE_A, MESURE_B, MESURE_C
MTL ATW 25-55 2014-12-04 00:00:00 AM 84 91 89
MTL ATW 25-55 2014-12-04 15:06:07 AM 0 0 0
MTL ATW 25-55 2014-12-04 16:22:37 AM 23 24 24
MTL ATW 25-55 2014-12-04 16:27:43 AM 34 40 39
MTL ATW 25-55 2014-12-04 16:27:59 AM 0 0 0
MTL ATW 25-55 2014-12-04 16:28:12 AM 51 58 57
Итак, я первый преобразовал столбец «EMH_PHASE» от «RAW_DATA» в 3-х distincts колонок («MESURE_A», «MESURE_B» и «MESURE_C») с кодом ниже.
WITH ROWS_TO_COLUMNS AS(
SELECT EMH_CED
,EMH_ID
,EMH_DATE_HEURE
,EMH_TYPE_MESURE
, MAX(decode(EMH_PHASE,'A', EMH_MESURE, null)) AS MESURE_A
, MAX(decode(EMH_PHASE,'B', EMH_MESURE, null)) AS MESURE_B
, MAX(decode(EMH_PHASE,'C', EMH_MESURE, null)) AS MESURE_C
FROM RAW_DATA
GROUP BY EMH_CED, EMH_ID, EMH_DATE_HEURE, EMH_TYPE_MESURE
)
До сих пор, похоже, я делаю то, что хочу, но получаю некоторые значения нулевых значений.
Затем я заполнил значения NULLS со значениями, которые были до каждого из них с этим кодом:
NULLS_FILLED AS(
SELECT EMH_CED, EMH_ID, EMH_DATE_HEURE
,FIRST_VALUE(MESURE_A) IGNORE NULLS
OVER (PARTITION BY EMH_CED, EMH_ID ORDER BY EMH_CED, EMH_ID, EMH_DATE_HEURE DESC
RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) AS MESURE_A
,FIRST_VALUE(MESURE_B) IGNORE NULLS
OVER (PARTITION BY EMH_CED, EMH_ID ORDER BY EMH_CED, EMH_ID, EMH_DATE_HEURE DESC
RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) AS MESURE_B
,FIRST_VALUE(MESURE_C) IGNORE NULLS
OVER (PARTITION BY EMH_CED, EMH_ID ORDER BY EMH_CED, EMH_ID, EMH_DATE_HEURE DESC
RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) AS MESURE_C
FROM ROWS_TO_COLUMNS
ORDER BY EMH_DATE_HEURE
)
Результат после этого операция была одна, я искал в самом начале.
Следующий шаг - это то, где мне нужна помощь. Я хочу получить только строки LEADing и LAGing, когда MESURE_A=MESURE_B=MESURE_C=0
(и мне тоже нужно показать эту строку).
Прямо сейчас, я могу получить только строки LAGing и самую последнюю строку таблицы, которую я даже не хочу. Мне все еще нужно выяснить способ получить 2 строки, которые я пропускаю, избавляясь от той, которую я не хочу.
Я пробовал разные вещи без каких-либо хороших результатов. Помогите?
Вот остальная часть моего кода, которые необходимо tweeked, чтобы получить желаемый результат:
,RN_DATA AS(
SELECT NULLS_FILLED.*, row_number() over (order by EMH_CED, EMH_ID, EMH_DATE_HEURE) AS rn
FROM NULLS_FILLED
)
,DATA_GROUPED AS (
SELECT RN_DATA.*, rownum - rn AS grp
FROM RN_DATA
WHERE MESURE_A>0 AND MESURE_B>0 AND MESURE_C>0
)
SELECT max(EMH_CED) keep (dense_rank first ORDER BY EMH_CED, EMH_ID, EMH_DATE_HEURE DESC) AS EMH_CED
,max(EMH_ID) keep (dense_rank first ORDER BY EMH_CED, EMH_ID, EMH_DATE_HEURE DESC) AS EMH_ID
,max(EMH_DATE_HEURE) keep (dense_rank first ORDER BY EMH_CED, EMH_ID, EMH_DATE_HEURE DESC) AS EMH_DATE_HEURE
,max(MESURE_A) keep (dense_rank first ORDER BY EMH_CED, EMH_ID, EMH_DATE_HEURE DESC) AS MESURE_A
,max(MESURE_B) keep (dense_rank first ORDER BY EMH_CED, EMH_ID, EMH_DATE_HEURE DESC) AS MESURE_B
,max(MESURE_C) keep (dense_rank first ORDER BY EMH_CED, EMH_ID, EMH_DATE_HEURE DESC) AS MESURE_C
,max(rn) keep (dense_rank first ORDER BY EMH_CED, EMH_ID, EMH_DATE_HEURE DESC) AS rn
FROM DATA_GROUPED
GROUP BY grp
ORDER BY rn
;
Не стесняйтесь проверить свой код с SQL Fiddle по адресу: http://sqlfiddle.com/#!4/e6b2e0/4/0
Это роман, а не вопрос. –