【问题标题】:How to JOIN 2 tables and keep only the most recent records如何加入 2 个表并仅保留最新记录
【发布时间】:2020-11-07 11:00:01
【问题描述】:

我有 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
)

这个查询确实执行了,但它给了我重复,并且绝对不会只过滤最近的记录。不知道我在这里做错了什么。

【问题讨论】:

  • 请提供样本数据和期望的结果。 db/sql fiddle 也会有所帮助。

标签: sql oracle join oracle12c


【解决方案1】:

列名(dte= Date, LOC = Location) 已更改,但您可以尝试以下简单查询来获取结果:

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) KEEP (DENSE_RANK FIRST order by dte desc) OVER (PARTITION BY a.item, a.loc)

【讨论】:

    【解决方案2】:

    良好的旧子选择也应该可以工作。 假设 unqiqe 每件商品的日期,位置对。

    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)  
                    
    

    【讨论】:

      【解决方案3】:

      我建议:

      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 不是最简单的语法,但它完全符合您的要求。

      【讨论】:

      • 我认为您误读了我的问题,但这仍然对我有用。历史数据不在价格表 (table2) 中,而是在库存表 (table1) 中。无论哪种方式,我都会试一试
      猜你喜欢
      • 1970-01-01
      • 2022-01-16
      • 2021-03-18
      • 2010-10-27
      • 2011-03-07
      • 1970-01-01
      • 1970-01-01
      • 2020-06-11
      • 2019-12-20
      相关资源
      最近更新 更多