在查询中丢弃旧数据时分组

时间:2018-06-04 02:57:12

标签: sql oracle group-by greatest-n-per-group

我有一张桌子(Oracle):

price
--------
integer id (pk)
integer part_id (fk)
number amount
timestamp change_timestamp

每当零件价格发生变化时,软件(不是我的)就会在此表中添加一个新行。它不是改变数据而是每个部分有一个条目,而是向表中添加一个新行。然后该软件查找最新条目。但是“旧的”数据仍然存在于表格中。

我正在尝试编写一个查询,告诉我a)当前(最新)价格和b)输入价格的日期。

我写了这个查询:

select part_id, amount, max(change_timestamp)
from price
group by part_id, amount

但这会返回该部分的每个条目,即使是旧条目。

如何在丢弃旧的无关数据的同时返回该日期的最新日期和金额?

不,我的数据库不是要更改的,要么是我的软件要更改。

2 个答案:

答案 0 :(得分:3)

  

但这会返回该部分的每个条目,即使是旧条目。

这是因为您按part_id, amount分组,每个part_id会考虑多个组,因为每个记录的金额不同。 要获得part_idMAX(timestamp),只需删除amountgroup by中的select即可。如果你想要金额,那么

您可以使用MAX分析函数找到change_timestamp

的记录
 SELECT part_id
    ,amount
    ,change_timestamp
FROM (
    SELECT p.*
        ,max(change_timestamp) OVER (PARTITION BY part_id) max_change_timestamp
    FROM price p
    )
WHERE change_timestamp = max_change_timestamp;

或者使用您在另一个答案中找到的row_number

或使用相关查询:

SELECT part_id
    ,amount
    ,change_timestamp
FROM price  p1
WHERE change_timestamp = (
        SELECT MAX(change_timestamp)
         FROM price p2
        WHERE p2.part_id = p1.part_id
        );

LAST(但并非最不重要)聚合函数:

SELECT part_id
    ,MAX(amount) KEEP DENSE_RANK(LAST ORDER BY change_timestamp)
    ,MAX(change_timestamp)
GROUP BY part_id;

答案 1 :(得分:0)

使用ROW_NUMBER()查找part_id的最新条目。

SELECT part_id
    ,amount
    ,change_timestamp
FROM (
    SELECT price.*
        ,ROW_NUMBER() OVER (PARTITION BY part_id ORDER BY change_timestamp DESC) as rn
    FROM price  
    )   
WHERE rn = 1