SQL SELECT несколько максимальных значений для даты - PullRequest
0 голосов
/ 01 июля 2019

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

Ниже вы найдете описательное изображение: Record that I want to obtain

Также, пожалуйста, найдите под запросом, который я использую:

SELECT *
  FROM item_forecast_detail 
  WHERE item_id = 177010 AND
        forecast_dt = (SELECT MAX(forecast_dt)
                         FROM item_forecast_detail
                         WHERE item_id = 177010) 
  ORDER BY forecast_dt DESC

Ответы [ 4 ]

0 голосов
/ 02 июля 2019

Вы можете использовать ROWNUM.

-- FETCH MAX FOR SINGLE item_id
WITH item_forecast_detail(item_id, forecast_dt, SOME_OTHER_COLS) AS (
SELECT 177010, DATE '2019-07-01','ANY VALUE - 1' FROM DUAL UNION ALL
SELECT 177010, DATE '2019-07-01','ANY VALUE - 2' FROM DUAL UNION ALL
SELECT 177010, DATE '2019-07-02','ANY VALUE - 4' FROM DUAL UNION ALL
SELECT 177010, DATE '2019-07-02','ANY VALUE - 5' FROM DUAL UNION ALL
SELECT 177010, DATE '2019-07-02','ANY VALUE - 6' FROM DUAL UNION ALL
SELECT 177011, DATE '2019-07-01','ANY VALUE - 1' FROM DUAL UNION ALL
SELECT 177011, DATE '2019-07-01','ANY VALUE - 1' FROM DUAL UNION ALL
SELECT 177011, DATE '2019-06-30','ANY VALUE - 1' FROM DUAL
)
SELECT
    ITEM_ID,
    FORECAST_DT,
    SOME_OTHER_COLS
FROM
    (
        SELECT
            ITEM_ID,
            FORECAST_DT,
            SOME_OTHER_COLS,
            ROW_NUMBER() OVER(
                PARTITION BY ITEM_ID
                ORDER BY
                    FORECAST_DT DESC
            ) AS RN
        FROM
            ITEM_FORECAST_DETAIL
        WHERE
            ITEM_ID = 177010
    )
WHERE
    RN = 1

OUTPUT

enter image description here

-- FETCH MAX FOR MULTIPLE item_id
WITH item_forecast_detail(item_id, forecast_dt, SOME_OTHER_COLS) AS (
SELECT 177010, DATE '2019-07-01','ANY VALUE - 1' FROM DUAL UNION ALL
SELECT 177010, DATE '2019-07-01','ANY VALUE - 2' FROM DUAL UNION ALL
SELECT 177010, DATE '2019-07-02','ANY VALUE - 4' FROM DUAL UNION ALL
SELECT 177010, DATE '2019-07-02','ANY VALUE - 5' FROM DUAL UNION ALL
SELECT 177010, DATE '2019-07-02','ANY VALUE - 6' FROM DUAL UNION ALL
SELECT 177011, DATE '2019-07-01','ANY VALUE - 1' FROM DUAL UNION ALL
SELECT 177011, DATE '2019-07-01','ANY VALUE - 1' FROM DUAL UNION ALL
SELECT 177011, DATE '2019-06-30','ANY VALUE - 1' FROM DUAL
)
SELECT
    ITEM_ID,
    FORECAST_DT,
    SOME_OTHER_COLS
FROM
    (
        SELECT
            ITEM_ID,
            FORECAST_DT,
            SOME_OTHER_COLS,
            ROW_NUMBER() OVER(
                PARTITION BY ITEM_ID
                ORDER BY
                    FORECAST_DT DESC
            ) AS RN
        FROM
            ITEM_FORECAST_DETAIL 
  --WHERE item_id = 177010
    )
WHERE
    RN = 1

OUTPUT

enter image description here

DB <> FIDDLE DEMO

Ура !!

0 голосов
/ 01 июля 2019

Один из вариантов - применить другое условие, например, получить последнюю версию starting_hour:

SQL> with item_forecast_Detail (item_id, forecast_dt, starting_hour) as
  2    (select 177010, date '2019-07-07', 21 from dual union all
  3     select 177010, date '2019-07-07', 18 from dual union all
  4     select 177010, date '2019-07-07', 15 from dual union all
  5     select 177010, date '2019-07-07', 12 from dual union all
  6     --
  7     select 123456, date '2019-02-17', 09 from dual
  8    )
  9  select *
 10  from item_forecast_Detail i
 11  where i.item_id = 177010
 12    and i.forecast_dt = (select max(i1.forecast_dt)
 13                         from item_forecast_detail i1
 14                         where i1.item_id = i.item_id
 15                        )
 16    and i.starting_hour = (select max(i2.starting_hour)
 17                           from item_forecast_detail i2
 18                           where i2.item_id = i.item_id
 19                          );

   ITEM_ID FORECAST_D STARTING_HOUR
---------- ---------- -------------
    177010 07.07.2019            21

SQL>

Еще один способ - отсортировать их с помощью аналитической функции и применить к окончательному запросу:

SQL> with item_forecast_Detail (item_id, forecast_dt, starting_hour) as
  2    (select 177010, date '2019-07-07', 21 from dual union all
  3     select 177010, date '2019-07-07', 18 from dual union all
  4     select 177010, date '2019-07-07', 15 from dual union all
  5     select 177010, date '2019-07-07', 12 from dual union all
  6     --
  7     select 123456, date '2019-02-17', 09 from dual
  8    ),
  9  sort as
 10    (select i.*,
 11            row_number() over (partition by item_id order by forecast_dt, starting_hour desc) rn
 12     from item_forecast_Detail i
 13    )
 14  select *
 15  from sort s
 16  where s.item_id = 177010
 17    and s.rn = 1;

   ITEM_ID FORECAST_D STARTING_HOUR         RN
---------- ---------- ------------- ----------
    177010 07.07.2019            21          1

SQL>
0 голосов
/ 02 июля 2019

Вы можете попробовать это с MySQL, SQLServer:

SELECT * FROM TABLE ORDER BY FORECAST_DT DESC LIMIT 1

SELECT TOP 1 * FROM Table ORDER BY FORECAST_DT DESC
0 голосов
/ 01 июля 2019

Используйте row_number() оконную аналитическую функцию для заказа по желанию и max(forecast_dt) over (order by forecast_dt desc) для определения самой последней даты

SELECT *
  FROM
  (
   SELECT d.*, 
          row_number() over (order by ending_hour desc) as rn,
          max(forecast_dt) over (order by forecast_dt desc) as mx
     FROM item_forecast_detail d
    WHERE item_id=177010 
   )
  WHERE mx = forecast_dt
  ORDER BY rn
...