如何联接2个表并仅保留最新记录

时间:2020-07-17 15:39:52

标签: sql oracle join oracle12c

我有2个表要加入。一个表是库存的历史记录,具有与每个“片断”相关的“最后更新”日期。另一张桌子列出了每件的价格。我想加入表格,以便获得每个价格的历史记录。例如。

                  TABLE 1
Date         Item        Location           QTY 
06/01/2020   ABC         123                10
06/01/2020   DEF         234                12
06/02/2020   ABC         345                13
06/06/2020   ABC         123                10


                  TABLE 2
ITEM         Price
ABC          34.5
DEF          52.12

-----------------> result table ------------------>
Date         Item        Location           QTY       Price
06/01/2020   DEF          234               12        34.5
06/02/2020   ABC          345               13        52.12
06/06/2020   ABC          123               10        34.5

过滤结果表的位置,以便仅保留最新记录。例如。 TABLE1每分钟更新一次,以显示新的库存水平。从表1在粒度的项目/位置级别的意义上说,项目+位置组合是“唯一的”。但是,表更新并创建新条目时,可能会有许多相同的项目/位置组合(这是一个历史表,因此具有相同项目+位置组合的旧条目保留在表中)。有时日期是不同的,有时日期是同一天。

我为尝试执行此操作而写的查询是:

SELECT DISTINCT
 TB1.DATE
,TB1.ITEM
,TB1.LOCATION
,TB1.QTY
,TB2.ITEM_COST

FROM
(
SCHEMA_1.TABLE1 AS TB1
JOIN  SCHEMA_1.TABLE2 AS TB2

ON TB1.ITEM = TB2.ITEM
JOIN (
      SELECT ITEM AS ITM,
          LOCATION AS LOC,
          MAX(DATE) AS MAXDATE
          FROM SCHEMA_1.TABLE1
          GROUP BY ITEM, LOCATION
      )TB3
  ON TB1.ITEM = TB3.ITM AND TB1.LOCATION= TB3.LOC AND TB1.DATE= TB3.MAXDATE
)

此查询确实执行,但是它给了我重复项,并且绝对不会仅针对最新记录进行过滤。不知道我在做什么错。

3 个答案:

答案 0 :(得分:1)

好的旧子选择也应该起作用。 假定每个项目的“取消日期”,“位置”对。

SELECT T1.* , T2.price 
FROM SCHEMA_1.TABLE1 AS TB1
JOIN SCHEMA_1.TABLE2 AS TB2 ON TB1.Item = TB2.Item
WHERE Date = (SELECT MAX(Date) FROM SCHEMA_1.TABLE1 AS TB3
              WHERE TB1.Item = TB3.Item
              AND   TB1.Location = TB3.Location)  
                

答案 1 :(得分:0)

我建议:

SELECT t1.*, t2.ITEM_PRICE
FROM SCHEMA_1.TABLE1 t1 JOIN
     (SELECT t2.ITEM, t2.LOCATION,
             MAX(t2.ITEM_PRICE) KEEP (DENSE_RANK FIRST ORDER BY t2.DATE DESC) as ITEM_PRICE
      FROM SCHEMA_1.TABLE2 t2
      GROUP BY t2.ITEM, t2.LOCATION
     ) t2
     USING (ITEM, LOCATION);

Oracle具有便捷的功能来获取组中的“第一个”或“最后一个”值。 KEEP并不是这项工作最简单的语法,但它确实可以满足您的要求。

答案 2 :(得分:0)

列名(dte =日期,LOC =位置)已更改,但是您可以尝试使用以下简单查询来获取结果:

Select dte dates, item, loc Locations, price, qty from 
(Select a.dte, a.item, a.loc,  b.price, a.qty,
max(a.dte) OVER (PARTITION BY a.item, a.loc) latest_dt 
from table1 a LEFT JOIN table2 b ON a.item = b.item) where dte = latest_dt
order by 1;

输出:

+-----------+------+-----------+-------+-----+
|   DATES   | ITEM | LOCATIONS | PRICE | QTY |
+-----------+------+-----------+-------+-----+
| 01-JUN-20 | DEF  | 234       | 52.12 | 12  |
+-----------+------+-----------+-------+-----+
| 02-JUN-20 | ABC  | 345       | 34.5  | 13  |
+-----------+------+-----------+-------+-----+
| 06-JUN-20 | ABC  | 123       | 34.5  | 10  |
+-----------+------+-----------+-------+-----+

您还可以获取最新日期,例如:max(a.dte)保持(由dte desc进行的DENSE_RANK第一订单)OVER(由a.item,a.loc分配)