使用ID和左联接的MAX

时间:2018-12-12 04:04:01

标签: sql oracle

这是我的桌子

表A

+-------------------+
| FILL_ID   COPY_ID |
+-------------------+
| 1         1       |
| 2         1       |
| 3         1       |
| 4         2       |
| 5         2       |
+-------------------+

表B  

+---------------------------------+
| SHIP_ID   Fill_ID    Shipdate   |
+---------------------------------+
| 1         1          1/1/18     |
| 2         2          2/1/18     |
| 3         4          5/1/18     |
| 4         5          6/1/18     |
+---------------------------------+
我希望查询结果为

+--------------------------------+
| COPY_ID  FILL_ID    SHIPDATE   |
+--------------------------------+
| 1        3        Null         |
| 2        5        6/1/18       |
+--------------------------------+

我的尝试之一

SELECT A.COPY_ID,
  MAX(A.FILL_ID),
  B.SHIPDATE
FROM A
LEFT B
ON A.FILL_ID             = B.FILL_ID
GROUP BY A.COPY_ID,
  B.UPDATED_AT

但是有了上面的代码,我得到了所有的填充ID

+--------------------------------+
| COPY_ID  FILL_ID    SHIPDATE   |
+--------------------------------+
| 1        1           1/1/18    |
| 1        2           2/1/18    |
| 1        3           Null      |
| 2        4           5/1/18    |
| 2        5           6/1/18    |
+--------------------------------+  

我已经尝试了许多不同的方法来使其正常工作,并以rownum = 1并依此类推。

4 个答案:

答案 0 :(得分:0)

假设fill_id在表b中是唯一的。可以利用以下内容。

with max_fill
  as (
select copy_id,max(fill_id) as max_fill_id
  from tablea
 group by copy_id
      )
   select a.copy_id
         ,a.max_fill_id
         ,b.shipdate
     from max_fill a
left join tableb b
   on a.max_fill_id=b.fill_id

答案 1 :(得分:0)

select c.copy_id, c.fill_id, b.shipdate
from (
     select copy_id, max(fill_id) fill_id
     from A
     group by copy_id
     ) c
left join B on c.fill_id = b.fill_id

答案 2 :(得分:0)

一个选择是使用max(a.fill_id) over (partition by a.copy_id order by a.fill_id desc)
其中aTableA 的别名):

  select copy_id, fill_id, Shipdate
    from
    (
    with TableA( fill_id, copy_id) as
        (
         select 1,1 from dual union all
         select 2,1 from dual union all
         select 3,1 from dual union all
         select 4,2 from dual union all
         select 5,2 from dual
        ),
        TableB( ship_id, fill_id, Shipdate) as
        (
         select 1,1,date'2018-01-01' from dual union all
         select 2,2,date'2018-01-02' from dual union all
         select 3,4,date'2018-01-05' from dual union all
         select 4,5,date'2018-01-06' from dual 
        )
     select a.copy_id, a.fill_id, b.Shipdate, 
            max(a.fill_id) over (partition by a.copy_id order by a.fill_id desc)
            as max_ship
       from TableA a
       full outer join TableB b on a.fill_id = b.fill_id
    )
     where fill_id = max_ship;

COPY_ID FILL_ID SHIPDATE
------- ------- --------------------
   1       3    NULL
   2       5    06.01.2018 00:00:00

对于上面已经存在的表,上面的查询被简化为:

  select copy_id, fill_id, Shipdate
    from
    (
     select a.copy_id, a.fill_id, b.Shipdate, 
            max(a.fill_id) over (partition by a.copy_id order by a.fill_id desc)
            as max_ship
       from TableA a
       full outer join TableB b on a.fill_id = b.fill_id
    )
     where fill_id = max_ship;

Rextester Demo

答案 3 :(得分:0)

在Oracle中,您可以使用keep功能通过group by获取最新值:

select a.copy_id, max(a.fill_id),
       max(b.shipdate) keep (dense_rank first order by a.fill_id desc nulls first) as shipdate
from a left join
     b
     on b.fill_id = a.fill_id
group by a.copy_id;