Выберите уникальную строку и предыдущее значение в пределах Oracle SQL - PullRequest
0 голосов
/ 07 августа 2020

Я использую таблицу, которая несколько раз повторяет одни и те же данные, и я хотел бы запросить ее, чтобы получить только самое последнее значение и значение перед ним. Таблица выглядит так:

+-------------+----------------+------+-------+
| Item Number | Effective Date | Cost | Price |
+-------------+----------------+------+-------+
|      1      |   01/01/2020   | 8.00 | 11.00 |
|      1      |   01/01/2020   | 8.00 | 10.50 |
|      2      |   09/22/2020   | 6.25 |  6.50 |
|      1      |   01/01/2020   | 8.00 | 10.50 |
|      1      |   05/07/2019   | 7.00 | 10.50 |
|      1      |   03/12/2018   | 6.00 | 10.50 |
|      2      |   03/12/2018   | 6.00 |  6.50 |
|      2      |   03/12/2018   | 6.00 |  6.50 |
|      1      |   01/01/2020   | 7.00 | 10.50 |
|      1      |   08/01/2016   | 5.25 | 10.50 |
+-------------+----------------+------+-------+

Я пытаюсь получить результаты запроса, чтобы указать дату только самой последней стоимости, а дату и стоимость были бы теми, которые были перед ней, и игнорировать все дубликаты таких данных:

+-------------+---------------+---------------+--------------+--------------+
| Item Number | Previous Date | Previous Cost | Current Date | Current Cost |
+-------------+---------------+---------------+--------------+--------------+
|      1      |   05/07/2019  |     7.00      |  01/01/2020  |     8.00     |
|      2      |   03/12/2018  |     6.00      |  09/22/2020  |     6.50     |
+-------------+---------------+---------------+--------------+--------------+

Я боролся с задержкой и секционированием, но я все еще получаю такие дубликаты:

+-------------+---------------+---------------+--------------+--------------+
| Item Number | Previous Date | Previous Cost | Current Date | Current Cost |
+-------------+---------------+---------------+--------------+--------------+
|      1      |   01/20/2020  |     8.00      |  01/01/2020  |     8.00     |
+-------------+---------------+---------------+--------------+--------------+

Спасибо за любые идеи, которые вы есть!

Ответы [ 2 ]

0 голосов
/ 07 августа 2020

Я могу предложить вам следующий подход.

with
    date_t as
    (
        select 1 as item_number, to_date('01/01/2020','mm/dd/yyyy') as effective_date, 8.00 as cost, 11.00 as price from dual union all
        select 1 as item_number, to_date('01/01/2020','mm/dd/yyyy') as effective_date, 8.00 as cost, 10.50 as price from dual union all
        select 2 as item_number, to_date('09/22/2020','mm/dd/yyyy') as effective_date, 6.25  as cost, 6.50 as price from dual union all
        select 1 as item_number, to_date('01/01/2020','mm/dd/yyyy') as effective_date, 8.00 as cost, 10.50 as price from dual union all
        select 1 as item_number, to_date('05/07/2019','mm/dd/yyyy') as effective_date, 7.00 as cost, 10.50 as price from dual union all
        select 1 as item_number, to_date('03/12/2018','mm/dd/yyyy') as effective_date, 6.00 as cost, 10.50 as price from dual union all
        select 2 as item_number, to_date('03/12/2018','mm/dd/yyyy') as effective_date, 6.00  as cost, 6.50 as price from dual union all
        select 2 as item_number, to_date('03/12/2018','mm/dd/yyyy') as effective_date, 6.00  as cost, 6.50 as price from dual union all
        select 1 as item_number, to_date('01/01/2020','mm/dd/yyyy') as effective_date, 7.00 as cost, 10.50 as price from dual union all
        select 1 as item_number, to_date('08/01/2016','mm/dd/yyyy') as effective_date, 5.25 as cost, 10.50 as price from dual 
    )
select 
    item_number,
    lag(effective_date) over (partition by item_number order by effective_date) as previous_date,
    lag(cost) over (partition by item_number order by effective_date) as previous_cost,
    effective_date as current_date,
    cost as current_cost
from    
    (
        select
            item_number,
            effective_date,
            max(cost) as cost
        from
            date_t  
        group by
            item_number,
            effective_date
        order by effective_date desc
    ) t 

Результат будет выглядеть так.

ITEM_NUMBER PREVIOUS_DATE   PREVIOUS_COST   CURRENT_DATE    CURRENT_COST
----------- -------------   -------------   ------------     ----------- 
1             null          null            01.08.2016       5.25
1             01.08.2016    5.25            12.03.2018       6
1             12.03.2018    6               07.05.2019       7
1             07.05.2019    7               01.01.2020       8
2             null          null            12.03.2018       6
2             12.03.2018    6               22.09.2020       6.25

Примечание: У меня есть другой формат даты в Oracle: dd.mm.yyyy.

0 голосов
/ 07 августа 2020

Я полагаю, вам нужно видеть последние две записи для каждого номера элемента всякий раз, когда он упорядочен по убыванию по столбцу даты. Я подготовил эту группировку и упорядочение вместе с удалением повторяющихся строк, используя DISTINCT в приведенном ниже запросе, но мы не знаем, какая стоимость является недавней для общей даты, которую заметил Страховщик. Я просто считал максимальное значение вашим результатом и характером инфляции :).

Я определил предыдущий и текущий столбцы с помощью функции ROW_NUMBER() на последнем шаге:

WITH t1 AS
(
 SELECT DISTINCT MAX(Cost) OVER (PARTITION BY Item_Number, Effective_Date) AS Cost,
        Item_Number, Effective_Date
   FROM tab 
  ORDER BY Item_Number, Effective_Date 
), t2 AS
(
 SELECT t1.*, 
        ROW_NUMBER() OVER (PARTITION BY Item_Number ORDER BY Effective_Date DESC) AS rn
   FROM t1  
)
SELECT Item_Number, 
       MAX(CASE WHEN rn = 2 THEN Effective_Date END) AS Previous_Date,
       MAX(CASE WHEN rn = 2 THEN Cost END) AS Previous_Cost,
       MAX(CASE WHEN rn = 1 THEN Effective_Date END) AS Current_Date,
       MAX(CASE WHEN rn = 1 THEN Cost END) AS Current_Cost       
  FROM t2   
 WHERE rn <= 2 
 GROUP BY Item_Number;

Демо

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...