每个项目的最大日期

Max date over each item

我有一个 table 简化后的样子:

WITH TBL (ITEM, COST, DAY) AS (
  SELECT 'A', 6, TO_DATE('2019-08-13', 'YYYY-MM-DD') FROM DUAL
  UNION ALL
  SELECT 'B', 4, TO_DATE('2019-08-21', 'YYYY-MM-DD') FROM DUAL
  UNION ALL
  SELECT 'B', 4, TO_DATE('2019-08-18', 'YYYY-MM-DD') FROM DUAL
  UNION ALL
  SELECT 'A', 2, TO_DATE('2019-08-21', 'YYYY-MM-DD') FROM DUAL
  UNION ALL
  SELECT 'B', 5, TO_DATE('2019-08-16', 'YYYY-MM-DD') FROM DUAL
  UNION ALL
  SELECT 'C', 2, TO_DATE('2019-08-15', 'YYYY-MM-DD') FROM DUAL
) SELECT ITEM, COST, DAY FROM TBL;


ITEM | COST | DAY
-----+------+--------------------
A    | 6    | 2019-08-13 00:00:00
B    | 4    | 2019-08-21 00:00:00
B    | 4    | 2019-08-18 00:00:00
A    | 2    | 2019-08-21 00:00:00
B    | 5    | 2019-08-16 00:00:00
C    | 2    | 2019-08-15 00:00:00

我想查询每件商品的最新价格

ITEM | COST | DAY
-----+------+--------------------
B    | 4    | 2019-08-21 00:00:00
A    | 2    | 2019-08-21 00:00:00
C    | 2    | 2019-08-15 00:00:00

我这样做的方法是让 CTE 获取每个项目的最新日期,然后 加盟费用。

WITH CTE (ITEM, DAY) AS (
  SELECT ITEM, MAX(DAY)
  FROM TBL
  GROUP BY ITEM
)
SELECT CTE.ITEM, TBL.COST, CTE.DAY
FROM CTE
JOIN TBL ON TBL.ITEM = CTE.ITEM AND TBL.DAY = CTE.DAY;

我的问题是是否有一种更简单的方法可以在没有 CTE 的情况下在一个查询中完成。

我尝试将 MAX 与 GROUP BY 结合使用,但没有找到任何方法使其发挥作用。

SELECT ITEM, COST, MAX(DAY)
FROM TBL
GROUP BY ITEM, COST;

它只对具有相同项目和成本的记录进行分组,而我实际需要的是将其与 MAX 天相应地分组。

ITEM | COST | DAY
-----+------+--------------------
A    | 6    | 2019-08-13 00:00:00
B    | 4    | 2019-08-21 00:00:00
A    | 2    | 2019-08-21 00:00:00
B    | 5    | 2019-08-16 00:00:00
C    | 2    | 2019-08-15 00:00:00

不存在:

SELECT t.ITEM, t.COST, t.DAY
FROM TBL t
WHERE NOT EXISTS (
  SELECT 1 FROM TBL
  WHERE ITEM = t.ITEM AND DAY > t.DAY
)

参见demo
结果:

> ITEM | COST | DAY      
> :--- | ---: | :--------
> A    |    2 | 21-AUG-19
> B    |    4 | 21-AUG-19
> C    |    2 | 15-AUG-19

您可以使用 row_number 分析函数,它将根据 partition byorder by 子句对每一行进行编号:

试试这个:

SELECT ITEM, COST, DAY FROM
(SELECT t.ITEM, t.COST, t.DAY,
ROW_NUMBER() over (partition by t.ITEM ORDER BY T.DAY DESC) AS RN
FROM TBL t)
WHERE RN = 1;

Demo

干杯!!

最简单的是 min/max 加上 first/last 选项:

select item, max(day), max(cost) keep (dense_rank last order by day) from tbl group by item;

demo

Link 到文档和示例。