【问题标题】:Oracle db query - multiple questions regarding join and returning only latest dateOracle 数据库查询 - 关于加入和仅返回最新日期的多个问题
【发布时间】:2017-08-24 10:06:01
【问题描述】:

我有 2 个表,Inventory 和 Transactions 在库存中,我有 Part_id、Location_Id 和 Zone_id 列(所有 VARCHAR) 在事务中,我有列 Part_id、代码和日期(Part_ID 和代码是 VARCHAR,日期是带有本地时区的 TIMESTAMP)

我想查看 Inventory 表中的所有 Part_id、Location_id 和 Zone_Id 以及一个列,如果存在,该列将从 transactions 表中返回该 Part_Id 的 Code 'Pick' 的最新日期,如果不存在,则返回该 Part_ID 的空白。 问题是 Tranasactions 可以将库存中的 Part_Id 与其他代码匹配。所以只去inventory.part_id = transactions.part_id 是行不通的。 并且当没有带有代码 Pick 的 Part_id 的记录时,如何获得返回的...

Inventory:                       Transactions:

│Part_ID│Location_ID│Zone_ID│    │Part_ID│Code   │Date
│a001   │A          │Z      │    │a001   │Pick   │01/01/2017│
│b002   │B          │X      │    │b002   │Check  │01/02/2017│
│c003   │C          │Y      │    │c003   │Receive│05/02/2017│
│d004   │D          │Q      │    │d004   │Pick   │09/02/2017│
                                 │a001   │Pick   │11/02/2017│

Wanted result:

│Part_ID│Location_ID│Zone_ID│LatestDateofPick│
│a001   │A          │Z      │11/02/2017      │
│b002   │B          │X      │                │
│c003   │C          │Y      │                │
│d004   │D          │Q      │09/02/2017      │

我只是 SQL 的初学者,所以我对此有点意见,请见谅。 :) 感谢您帮助我解决这个问题!

【问题讨论】:

  • 使用 OUTER JOIN、MAX 函数和 GROUP BY 子句。
  • 我要做的是在 transactions 表中找到每个 part_id 的最新选择日期(提示:聚合查询适用于此)。然后,只需将该聚合子查询外部连接回库存表即可。鉴于这些信息,为什么不尝试自己编写查询呢?如果您遇到困难,请更新您的问题以包含您尝试过的内容,我们会从那里为您提供帮助

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


【解决方案1】:

我使用外部联接和日期的最大值看到了这一点

  -- Start test data
  with inventory (part_id, location_id, zone_id) as
       (select 'a001','A','Z' from dual union all
        select 'b002','B','X' from dual union all
        select 'c003','C','Y' from dual union all
        select 'd004','D','Q' from dual),
       transaction (part_id, code, txn_date) as 
       (select 'a001','Pick',to_date( '01-jan-17','DD-MON-RR') from dual union all
        select 'b002','Check',to_date( '02-JAN-17','DD-MON-RR') from dual union all
        select 'c003','Receive',to_date( '02-may-17','DD-MON-RR') from dual union all
        select 'd004','Pick',to_date( '02-sep-17','DD-MON-RR') from dual union all
        select 'a001','Pick',to_date( '02-nov-17','DD-MON-RR') from dual)
  -- end test data      
select inv.part_id,
       inv.location_id,
       inv.zone_id,
       MAX(txn.txn_date)
from inventory inv
     left outer join transaction txn on (inv.part_id = txn.part_id AND txn.code = 'Pick')
group by inv.part_id, inv.location_id, inv.zone_id;


"PART_ID"             "LOCATION_ID"         "ZONE_ID"     MAX(TXN.TXN_DATE)"           
"d004"                "D"                   "Q"           "09/02/2017 00:00:00"         
"c003"                "C"                   "Y"           ""                            
"a001"                "A"                   "Z"           "11/02/2017 00:00:00"         
"b002"                "B"                   "X"           ""                            

【讨论】:

    【解决方案2】:

    你需要这样的东西才能得到你想要的东西

    select t.Part_ID,
        i.Location_ID,
        i.Zone_ID,
        case when t.Code <> 'Pick' then null else max(t.Date) end as LatestDateOfPick
    from Transactions t
    join Inventory  i on t.Part_ID = i.Part_ID
    group by t.Part_ID,i.Location_ID,i.Zone_ID,t.Code
    

    这只会在它“选择”代码时提取max日期,否则它将离开它NULL

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-06
      • 1970-01-01
      • 1970-01-01
      • 2020-11-14
      • 2022-11-14
      相关资源
      最近更新 更多