2015-11-11 7 views
0

(С учетом этой базы данных SQL Fiddle)В Oracle 11gR1 как я могу включать датируемые значения впору вне из WHERE между пунктом временной метки

Как я могу выбрать предыдущее значение прямо у меня, где между пунктом в запрос ниже?

Если это возможно, это устранит мой другой запрос, необходимый для поиска этого значения в моем макросе ADOBB VBA excel. Поскольку я в настоящее время цикл, хотя расширение моего "ГДЕ МЕЖДУ TIMESTAMP и TIMESTAMP" искать экспоненциально до тех пор, пока не будет найдено значение времени до отметки времени.

Средство взвешенного по времени (TWA) в окончательной инструкции выбора не будет точным, если у меня нет реального значения VALUE в начале самого первого интервала. (Все остальные промежутки между ними в порядке, и запрос выполняется нормально). Данные, которые были перенесены в мой экземпляр Oracle 11GR1, являются случайными, и это не известно вообще, поскольку могут существовать большие пробелы. Таким образом, стоимость не будет присутствовать в течение часов, дней, месяцев или иногда даже лет.

-- Lets Begin the Query 
WITH INPUTS AS ( 
    SELECT RECNM, 
      TO_TIMESTAMP_TZ ('15-01-01 00:10:00 AMERICA/LOS_ANGELES','RR-MM-DD HH24:MI:SS TZR') AS START_TIME, 
      TO_TIMESTAMP_TZ ('15-01-01 00:30:59 AMERICA/LOS_ANGELES','RR-MM-DD HH24:MI:SS TZR') AS END_TIME 
    FROM POINTS 
    WHERE ACRONYM = 'WELL32-PSI' 
) , 
ALL_INTERVALS AS ( 
    SELECT RECNM, 
     START_TIME + NUMTODSINTERVAL ((LEVEL-1) , 'MINUTE') AS TIME 
    FROM INPUTS 
    CONNECT BY 
    LEVEL-1 <= 
       EXTRACT (DAY FROM END_TIME - START_TIME) * 24 * 60 + 
       EXTRACT (HOUR FROM END_TIME - START_TIME) * 60 + 
       EXTRACT (MINUTE FROM END_TIME - START_TIME) 
) , 
ALL_TIMES AS ( 
    SELECT 
     TIME, 
     VALUE, 
     1 AS HAS_VALUE 
    FROM HST H 
    INNER JOIN INPUTS I 
     ON (H.RECNM = I.RECNM 
     AND H.TIME BETWEEN CAST (I.START_TIME AS TIMESTAMP) 
     AND CAST (I.END_TIME AS TIMESTAMP)) 
    UNION ALL 
    SELECT 
     TIME, 
     NULL, 
     0 
    FROM ALL_INTERVALS 
    ORDER BY TIME,1, 2 NULLS FIRST 
) , 
LEAD_LAG_TIMES AS ( 
    SELECT 
     TIME, 
     LAST_VALUE (VALUE IGNORE NULLS) OVER (ORDER BY TIME ASC, VALUE ASC) AS VALUE, 
     24 * 60 * 60 * EXTRACT (DAY FROM LEAD (TIME) OVER (ORDER BY TIME ASC,VALUE ASC) -TIME) + 
       60 * 60 * EXTRACT (HOUR FROM LEAD (TIME) OVER (ORDER BY TIME ASC,VALUE ASC) -TIME) + 
        60 * EXTRACT (MINUTE FROM LEAD (TIME) OVER (ORDER BY TIME ASC,VALUE ASC) -TIME) + 
         EXTRACT (SECOND FROM LEAD (TIME) OVER (ORDER BY TIME ASC,VALUE ASC) -TIME) AS DURATION 
    FROM ALL_TIMES 
) 
SELECT CAST (TRUNC (TIME,'MI') AS TIMESTAMP WITH TIME ZONE) AS TIME, 
    SUM (VALUE * DURATION)/SUM (DURATION) AS TWA, 
    SUM (DURATION) AS TOTAL_DURATION 
FROM LEAD_LAG_TIMES 
GROUP BY CAST (TRUNC (TIME,'MI') AS TIMESTAMP WITH TIME ZONE) 
ORDER BY TIME ASC 

Пример

2015-01-01 00:00:00 AMERICA/LOS_ANGELES  63.3 
2015-01-01 00:00:08 AMERICA/LOS_ANGELES  63.7 
2015-01-01 00:00:17 AMERICA/LOS_ANGELES  64.6 
2015-01-01 00:00:28 AMERICA/LOS_ANGELES  66.3 
2015-01-01 00:00:45 AMERICA/LOS_ANGELES  66.8 
2015-01-01 00:00:55 AMERICA/LOS_ANGELES  67.5 
2015-01-01 00:01:11 AMERICA/LOS_ANGELES  67.0 
2015-01-01 00:01:30 AMERICA/LOS_ANGELES  67.4 
2015-01-01 00:01:40 AMERICA/LOS_ANGELES  67.9 
2015-01-01 00:01:50 AMERICA/LOS_ANGELES  68.7 
2015-01-01 00:02:01 AMERICA/LOS_ANGELES  68.2 
2015-01-01 00:02:11 AMERICA/LOS_ANGELES  67.1 
2015-01-01 00:02:21 AMERICA/LOS_ANGELES  66.5 
2015-01-01 00:02:31 AMERICA/LOS_ANGELES  65.5 
2015-01-01 00:02:46 AMERICA/LOS_ANGELES  65.0 
2015-01-01 00:02:59 AMERICA/LOS_ANGELES  64.6 
2015-01-01 00:03:15 AMERICA/LOS_ANGELES  64.1 
2015-01-01 00:03:25 AMERICA/LOS_ANGELES  63.2 
2015-01-01 00:03:35 AMERICA/LOS_ANGELES  62.7 
2015-01-01 00:04:05 AMERICA/LOS_ANGELES  62.2 
2015-01-01 00:04:32 AMERICA/LOS_ANGELES  61.8 
2015-01-01 00:05:40 AMERICA/LOS_ANGELES  61.3 
2015-01-01 00:05:55 AMERICA/LOS_ANGELES  60.8-----Not Included in where between but this value is needed 
2015-01-01 00:10:20 AMERICA/LOS_ANGELES  60.3--------- Included in where between 
2015-01-01 00:10:38 AMERICA/LOS_ANGELES  60.9 
2015-01-01 00:10:48 AMERICA/LOS_ANGELES  61.3 
2015-01-01 00:10:58 AMERICA/LOS_ANGELES  61.8 
2015-01-01 00:11:27 AMERICA/LOS_ANGELES  62.3 
2015-01-01 00:13:54 AMERICA/LOS_ANGELES  61.8 
2015-01-01 00:14:10 AMERICA/LOS_ANGELES  61.4 
2015-01-01 00:14:41 AMERICA/LOS_ANGELES  60.9 
2015-01-01 00:15:18 AMERICA/LOS_ANGELES  61.4 
2015-01-01 00:15:51 AMERICA/LOS_ANGELES  60.9 
2015-01-01 00:16:19 AMERICA/LOS_ANGELES  60.4 
2015-01-01 00:16:32 AMERICA/LOS_ANGELES  59.9 
2015-01-01 00:17:04 AMERICA/LOS_ANGELES  59.4 
2015-01-01 00:17:27 AMERICA/LOS_ANGELES  59.9 
2015-01-01 00:17:37 AMERICA/LOS_ANGELES  59.4 
2015-01-01 00:17:58 AMERICA/LOS_ANGELES  59.0 
2015-01-01 00:18:22 AMERICA/LOS_ANGELES  59.4 
2015-01-01 00:18:50 AMERICA/LOS_ANGELES  59.9 
2015-01-01 00:19:00 AMERICA/LOS_ANGELES  60.3 
2015-01-01 00:19:25 AMERICA/LOS_ANGELES  60.8 
2015-01-01 00:19:34 AMERICA/LOS_ANGELES  61.4 
2015-01-01 00:19:45 AMERICA/LOS_ANGELES  62.1 
2015-01-01 00:19:55 AMERICA/LOS_ANGELES  62.5 
2015-01-01 00:20:30 AMERICA/LOS_ANGELES  63.0 
2015-01-01 00:20:51 AMERICA/LOS_ANGELES  63.5 
2015-01-01 00:21:03 AMERICA/LOS_ANGELES  63.9 
2015-01-01 00:22:04 AMERICA/LOS_ANGELES  64.4 
2015-01-01 00:22:28 AMERICA/LOS_ANGELES  64.8 
2015-01-01 00:23:17 AMERICA/LOS_ANGELES  64.4 
2015-01-01 00:23:27 AMERICA/LOS_ANGELES  63.9 
2015-01-01 00:24:31 AMERICA/LOS_ANGELES  63.4 
2015-01-01 00:26:06 AMERICA/LOS_ANGELES  63.0 
2015-01-01 00:27:20 AMERICA/LOS_ANGELES  62.5 
2015-01-01 00:27:30 AMERICA/LOS_ANGELES  61.9 
2015-01-01 00:28:08 AMERICA/LOS_ANGELES  62.4 
2015-01-01 00:28:37 AMERICA/LOS_ANGELES  62.0 
2015-01-01 00:29:21 AMERICA/LOS_ANGELES  62.5 
2015-01-01 00:29:38 AMERICA/LOS_ANGELES  62.9 
2015-01-01 00:31:27 AMERICA/LOS_ANGELES  62.5 
2015-01-01 00:32:01 AMERICA/LOS_ANGELES  62.0 
2015-01-01 00:32:25 AMERICA/LOS_ANGELES  62.5 
2015-01-01 00:35:07 AMERICA/LOS_ANGELES  62.9 
2015-01-01 00:35:56 AMERICA/LOS_ANGELES  62.5 
2015-01-01 00:36:06 AMERICA/LOS_ANGELES  62.0 
2015-01-01 00:36:59 AMERICA/LOS_ANGELES  61.5 
2015-01-01 00:39:31 AMERICA/LOS_ANGELES  62.0 
2015-01-01 00:40:12 AMERICA/LOS_ANGELES  61.5 
2015-01-01 00:40:22 AMERICA/LOS_ANGELES  60.9 
2015-01-01 00:40:35 AMERICA/LOS_ANGELES  60.5 
2015-01-01 00:40:55 AMERICA/LOS_ANGELES  60.0 
2015-01-01 00:41:22 AMERICA/LOS_ANGELES  60.5 
2015-01-01 00:41:46 AMERICA/LOS_ANGELES  60.1 
2015-01-01 00:42:31 AMERICA/LOS_ANGELES  60.6 
+0

Ваш третий экстракт должен быть MINUTE, а не SECOND? При этом ваш запрос получает 21 строку, каждый из которых имеет TWA null и DURATION 60. Что вы хотите получить вместо этого? те же, но две дополнительные строки, один до и один после периода ввода? –

+0

Я исправил запрос, спасибо, что указал на это! Я все еще хочу 21 строку. поскольку есть 21 минута, мне нужно ALL_TIMES включить время/значение до и после моего периода ввода, если это вообще возможно. –

+0

ОК, понял, почему я все получаю; «cast ... to timestamp» теряет часовой пояс, поэтому вне LA TZR получат разные результаты; но если это должно быть «с часовым поясом», то оно избыточно ... Является ли строка до предполагаемой 00:05 на основе данных HST или 00:09 на основе периода времени? –

ответ

1

Не совсем уверен, что это именно то, что вам нужно, но вы можете включить последнюю запись до и после периода путем добавления еще двух запросов к вашему ALL_TIMES КТР:

UNION ALL 
SELECT 
    MAX(H.TIME) KEEP (DENSE_RANK FIRST ORDER BY H.TIME DESC) AS TIME, 
    MAX(H.VALUE) KEEP (DENSE_RANK FIRST ORDER BY H.TIME DESC), 
    1 
FROM INPUTS I 
INNER JOIN HST H 
    ON H.TIME < I.START_TIME 
UNION ALL 
SELECT 
    MIN(H.TIME) KEEP (DENSE_RANK FIRST ORDER BY H.TIME) AS TIME, 
    MIN(H.VALUE) KEEP (DENSE_RANK FIRST ORDER BY H.TIME), 
    1 
FROM INPUTS I 
INNER JOIN HST H 
    ON H.TIME > I.END_TIME 

Первый получает время и значение для последней строки перед вашим диапазоном; второй получает то же самое для первой строки после диапазона.

От оригинала (ну, немного подправили) запрос я получаю:

TIME           TWA TOTAL_DURATION 
------------------------------------------ ------ -------------- 
01-JAN-15 00.10.00.000000000 EUROPE/LONDON 40.5    60 
01-JAN-15 00.11.00.000000000 EUROPE/LONDON 62.1    60 
... 
01-JAN-15 00.29.00.000000000 EUROPE/LONDON 62.5    60 
01-JAN-15 00.30.00.000000000 EUROPE/LONDON      

С этими дополнительными союзами я получаю:

TIME           TWA TOTAL_DURATION 
------------------------------------------ ------ -------------- 
01-JAN-15 00.05.00.000000000 EUROPE/LONDON 60.8   245 
01-JAN-15 00.10.00.000000000 EUROPE/LONDON 60.8    60 
01-JAN-15 00.11.00.000000000 EUROPE/LONDON 62.1    60 
... 
01-JAN-15 00.29.00.000000000 EUROPE/LONDON 62.5    60 
01-JAN-15 00.30.00.000000000 EUROPE/LONDON 62.9    87 
01-JAN-15 00.31.00.000000000 EUROPE/LONDON      

Я вижу Лондон раз из-за CAST (TRUNC (TIME,'MI') AS TIMESTAMP WITH TIME ZONE); TRUNC делает его DATE, без информации о часовом поясе; CAST затем преобразует его в мой часовой пояс сеанса. (Вот почему для меня была проблема с избыточным CAST(... TO TIMEZONE)). Если вы всегда будете запускать его в целевом TZ, тогда это может не иметь значения, но в противном случае вам нужно будет сделать некоторые манипуляции, чтобы сохранить нормальные значения.

+0

Приветствия! Я пытаюсь это сделать прямо сейчас, Большое вам спасибо! –

+0

Если вы хотите использовать дополнительную ценность, когда в первом/последнем периоде ничего нет, это сложнее, но, по крайней мере, делает эту информацию доступной, я полагаю. Возможно, вам нужно будет сделать больше работы со свинцом/запаздыванием. Однако я не уверен, какую логику вы бы использовали. –

+0

Я думаю, что это сработает, но запрос займет очень много времени, так как эти данные возвращаются на 24 года. Есть ли уловка для размещения 00:05:55 Значение для 00:10:00 значение, если 00:10:00 было null? Я видел (+) оператор, но я читаю на нем. –

 Смежные вопросы

  • Нет связанных вопросов^_^