简体   繁体   中英

Return the article with the latest date, sql max(DATE)

I have the following query:

 SELECT  MAX(b.upd_dtime) as MaxT, b.vo_no as vo_no, y.item_no
 FROM vo_order_t b JOIN (
     SELECT a.vo_no, a.item_no FROM vo_item_t a where a.item_no IN('00265929')) y ON y.vo_no = b.vo_no
 GROUP BY b.vo_no, y.item_no

The output from this query is the following:

Date                Vo_No   Item_No
2019-05-27 08:37:07 0242625 00265929
2019-05-27 07:52:29 0282971 00265929
2019-05-27 07:52:29 0282972 00265929
2019-05-27 07:52:29 0696864 00265929
2018-02-13 22:57:09 0282984 00265929
2019-05-27 07:52:29 0395347 00265929
2019-05-27 07:52:29 0242712 00265929
2019-05-27 07:52:29 0242624 00265929
2019-05-27 07:52:29 0441449 00265929
2019-05-27 07:52:29 0400026 00265929

But I want the output to be the following:

Date                Vo_no   Item_No
2019-05-27 08:37:07 0242625 00265929

How can I modify my query to achieve that?

You can use the keep clause of aggregates to return the first/last value, ordered by another:

create table t (
  c1 date, c2 varchar2(10), c3 varchar2(10)
);
alter session set nls_date_format = 'YYYY-MM-DD HH24:MI:SS';

insert into t values ( '2019-05-27 08:37:07', '0242625', '00265929' );
insert into t values ( '2019-05-27 07:52:29', '0282971', '00265929' );
insert into t values ( '2019-05-27 07:52:29', '0282972', '00265929' );
insert into t values ( '2019-05-27 07:52:29', '0696864', '00265929' );
insert into t values ( '2018-02-13 22:57:09', '0282984', '00265929' );
insert into t values ( '2019-05-27 07:52:29', '0395347', '00265929' );
insert into t values ( '2019-05-27 07:52:29', '0242712', '00265929' );
insert into t values ( '2019-05-27 07:52:29', '0242624', '00265929' );
insert into t values ( '2019-05-27 07:52:29', '0441449', '00265929' );
insert into t values ( '2019-05-27 07:52:29', '0400026', '00265929' );

select max ( c1 ) c1,
       max ( c2 ) keep (
         dense_rank first
         order by c1 desc
       ) c2,
       c3
from   t
group  by c3;

C1                    C2        C3         
2019-05-27 08:37:07   0242625   00265929   

Analytic functions might help. Code you need begins at line #6.

SQL> with test (upd_dtime, vo_no, item_no) as
  2    (select 20190527, 242625, 265929 from dual union all
  3     select 20190213, 282984, 265929 from dual union all
  4     select 20190118, 400026, 265929 from dual
  5    )
  6  select upd_dtime, vo_no, item_no
  7  from (
  8         select upd_dtime, vo_no, item_no,
  9           row_number() over (partition by item_no order by upd_dtime desc) rn
 10         from test
 11       )
 12  where rn = 1;

 UPD_DTIME      VO_NO    ITEM_NO
---------- ---------- ----------
  20190527     242625     265929

SQL>

[EDIT: applied to your tables]

As you were unable to adjust the above code to your real tables (next time, it would be a good idea to post test case which includes CREATE TABLE and INSERT INTO sample data), here's how it might look like:

  • yourq CTE represents query you posted. I don't know why you used an inline view (its alias was y ); why didn't you simply join vo_order_t and vo_item_t , as I did?
  • the rest is exactly the same as I posted it previously

So: copy/paste this code and execute it in your schema. If I didn't make any typo, it should be OK. If not, as I said - post test case.

with 
yourq as
-- your query, rewritten
  (select b.upd_dtime, b.vo_no, a.item_no
   from vo_order_t b join vo_item_t a on a.vo_no = b.vo_no
   where a.item_no = '00265929'
  )
select upd_dtime, vo_no, item_no
from (
      select upd_dtime, vo_no, item_no,
             row_number() over (partition by item_no order by upd_dtime desc) rn
      from yourq
     )
where rn = 1; 

You can use MAX() OVER (PARTITION BY ...) analytic function :

WITH t AS
(   
 SELECT MAX(v.upd_dtime) OVER (PARTITION BY v.item_no) AS MaxT, 
        v.vo_no AS vo_no, v.item_no, v.upd_dtime 
   FROM vo_order_t v
  WHERE v.item_no = '00265929'
)
SELECT *
  FROM t
 WHERE upd_dtime = MaxT   

If you're using version 12c+, then directly use FETCH FIRST 1 ROW ONLY to get the latest article :

 SELECT MAX(v.upd_dtime) OVER (PARTITION BY v.item_no) AS MaxT, 
        v.vo_no AS vo_no, v.item_no, v.upd_dtime 
   FROM vo_order_t v
  WHERE v.item_no = '00265929'
  FETCH FIRST 1 ROW ONLY

Demo

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM