2016-12-01 8 views
0

Мой текущий оператор вытягивает цены из таблицы, где совокупность текущей цены связана с максимальной или самой последней датой, найденной в таблице. Последней ценой для записи является цена со второго максимального дня, найденного в таблице.sql db2 - максимальная дата и вторая максимальная дата для прокатки 30 дней

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

SELECT 
T1.ID 
T1.DT_PRICE 
T1.PRICE 
T2.LAST_DT_PRICE, 
T2.LAST_PRICE 

FROM  
(SELECT  
    fpr.ID, 
    fpr.DT_PRICE, 
    fpr.PRICE 
    FROM UDBADM.PRICES fpr  

    WHERE fpr.DT_PRICE = (select max(DT_PRICE) 
         from UDBADM.PRICES) 
    AND fpr.CD_PRICE = 'C' 
) T1 

LEFT JOIN 
    (SELECT 
    fpr2.ID, 
    fpr2.DT_PRICE AS LAST_DT_PRICE, 
    fpr2.PRICE AS LAST_PRICE 
    FROM UDBADM.PRICES fpr2 

    WHERE fpr2.DT_PRCE = (select max(DT_PRICE) 
         from UDBADM.PRICES 
         where DT_PRICE < (select 
              max(DT_PRICE) 
              from UDBADM.PRICES)) 
    AND fpr2.CD_PRICE = 'C' 
) T2 
ON T1.ID = T2.ID 

Выходной ток на 1 запись:

ID  DT_PRICE PRICE LAST_DT_PRICE LAST_PRICE 
B5199 11/30/2016 50.3 11/29/2016  50.1 

Ожидаемый выход на 1 запись с холмистой 30 дней:

ID  DT_PRICE PRICE LAST_DT_PRICE LAST_PRICE 
B5199 10/18/2016 50.1 10/17/2016  50 
B5199 10/19/2016 50  10/18/2016  50.1 
B5199 10/20/2016 49.75 10/19/2016  50 
B5199 10/21/2016 49.8 10/20/2016  49.75 
B5199 10/24/2016 50.12 10/21/2016  49.8 
B5199 10/25/2016 50.2 10/24/2016  50.12 
B5199 10/26/2016 50.25 10/25/2016  50.2 
B5199 10/27/2016 50.1 10/26/2016  50.25 
B5199 10/28/2016 49.8 10/27/2016  50.1 
B5199 10/31/2016 49.5 10/28/2016  49.8 
B5199 11/1/2016 49.2 10/31/2016  49.5 
B5199 11/2/2016 50  11/1/2016  49.2 
B5199 11/3/2016 50.1 11/2/2016  50 
B5199 11/4/2016 50  11/3/2016  50.1 
B5199 11/7/2016 49.75 11/4/2016  50 
B5199 11/8/2016 49.8 11/7/2016  49.75 
B5199 11/9/2016 50  11/8/2016  49.8 
B5199 11/10/2016 50  11/9/2016  50 
B5199 11/14/2016 50.1 11/10/2016  50 
B5199 11/15/2016 50.1 11/14/2016  50.1 
B5199 11/16/2016 49.8 11/15/2016  50.1 
B5199 11/17/2016 49.5 11/16/2016  49.8 
B5199 11/18/2016 49.2 11/17/2016  49.5 
B5199 11/21/2016 48.9 11/18/2016  49.2 
B5199 11/22/2016 49.8 11/21/2016  48.9 
B5199 11/23/2016 50.2 11/22/2016  49.8 
B5199 11/25/2016 50.2 11/23/2016  50.2 
B5199 11/28/2016 50.2 11/25/2016  50.2 
B5199 11/29/2016 50.1 11/28/2016  50.2 
B5199 11/30/2016 50.3 11/29/2016  50.1 
+0

К сожалению не понимаю вашу логику. Также покажите нам пример данных, чтобы получить этот результат. Пожалуйста, прочитайте [** How-to-Ask **] (http://stackoverflow.com/help/how-to-ask) \t \t И вот отличный место [** START **] (http://spaghettidba.com/2015/04/24/how-to-post-at-sql-question-on-a-public-forum/), чтобы узнать, как улучшить ваши качество вопроса и получить лучшие ответы. –

ответ

0
WITH cte AS (
    SELECT 
     fpr.Id 
     ,fpr.DT_PRICE 
     ,fpr.PRICE 
     ,ROW_NUMBER() OVER (PARTITION BY fpr.Id ORDER BY fpr.DT_PRICE) as IdRowNumber 
    FROM 
     UDBADM.PRICES fpr 
    WHERE 
     fpr.CE_PRICE = 'C' 
     AND fpr.DT_PIRCE >= '10/23/2016' 
) 

SELECT 
    c1.Id 
    ,c1.DT_PRICE 
    ,c1.PRICE 
    ,c2.DT_PRICE as LAST_PRICE_DATE 
    ,c2.PRICE as LAST_PRICE 
FROM 
    cte c1 
    INNER JOIN cte c2 
    ON c1.Id = c2.Id 
    AND c1.IdRowNumber = c2.IdRowNumber + 1 

Потому что у вас есть пробелы в ваших дат вы могли бы генерировать row_number, основанный на дате, а затем используйте номер строки в самостоятельном соединении, чтобы получить цену раньше. Обратите внимание, что INNER JOIN предоставит вам точный результат, но вы можете рассмотреть LEFT JOIN, чтобы у вас была начальная дата цены 11/17/2016, но это зависит от вас.

Что касается ограничения на 30 дней, как это сделать, это будет зависеть от того, что вы подразумеваете под этим.

Если вы хотите получить любые цены за последние 30 дней, добавьте условия, в которых используется выражение Common Table Expression, которое ищет DT_PRICE> текущую дату - 30 дней.

Однако, если вы хотите последние 30 ценовые рекорды, независимо от даты, то просто переверните row_number быть DESCENDING и выбрать первые 30 записей, как это:

WITH cte AS (
    SELECT 
     fpr.Id 
     ,fpr.DT_PRICE 
     ,fpr.PRICE 
     ,ROW_NUMBER() OVER (PARTITION BY fpr.Id ORDER BY fpr.DT_PRICE DESC) as IdRowNumber 
    FROM 
     UDBADM.PRICES fpr 
    WHERE 
     fpr.CE_PRICE = 'C' 
) 

SELECT 
    c1.Id 
    ,c1.DT_PRICE 
    ,c1.PRICE 
    ,c2.DT_PRICE as LAST_PRICE_DATE 
    ,c2.PRICE as LAST_PRICE 
FROM 
    cte c1 
    INNER JOIN cte c2 
    ON c1.Id = c2.Id 
    AND c1.IdRowNumber = c2.IdRowNumber - 1 
WHERE 
    c1.IdRowNumber <= 30 
+0

Эй, @ Matt, первое заявление, которое вы выложили, отлично поработало! Спасибо! Где именно следует вводить диапазон дат DT_PRICE или Max Number of RowNumbers для возврата? Я попытался ввести оператор AND в самом конце CTE и сказал: И fpr.DT_PIRCE> = '11/23/2016 ', например, чтобы получить несколько дней - я заметил одно: если запись новая и делает не имеют LAST_PRICE_DATE и LAST_PRICE, он не отображается в выводе. Есть ли быстрое решение включить записи, имеющие NULLS для LAST_PRICE_DATE и LAST_PRICE? – steveW

+0

@steveW добро пожаловать. спасибо за принятие, не забудьте также поднять. Что касается места ввода максимальных строк или минимальной даты, которая зависит от того, что вы хотите, например. 30 записей, то используйте второй оператор, который ограничивает записи. Если вы хотите в течение последних 30 дней, то введите в cte AND DT_PRICE, я отредактировал это, чтобы сделать его более понятным. Надеюсь, вы все настроены. cheers – Matt

+0

Просто еще одна вещь. Рекомендуете ли вы добавлять дополнительный запрос или корректировать инструкцию и в OR для учета записей, где последняя дата и цена NULL? В настоящий момент запрос исключает любую запись с последней датой и ценой NULL. – steveW