How to return only latest record on join [duplicate]

℡╲_俬逩灬. 提交于 2021-02-09 02:45:37

问题


I'm joining tables. I only want to return one record from the joining table, based on a date field.

Here's a simplified fiddle of what I've done so far: http://sqlfiddle.com/#!3/be0cdd/2

My tables:

  CUSTOMER

| CustomerID |
--------------
| 1          |


  PURCHASE

| PurchaseID | CustomerID | ProductID | CreateDate | ArchiveFlag |
------------------------------------------------------------------
| 1          | 1          | 443       | 01-FEB-15  | F           |
| 2          | 1          | 551       | 01-MAR-15  | F           |
| 3          | 1          | 151       | 01-JAN-15  | F           |
| 4          | 1          | 654       | 01-MAY-15  | T           |
| 5          | 1          | 345       | 01-APR-15  | T           |

and here's the query itself:

select *
from customer c
join purchase p
on c.customerid = p.customerid
and p.archiveflag = 'F';

I only want to return the latest purchase that isn't archived (in this example, purchase ID 2) for each customer.

Ideal output:

| CustomerID | PurchaseID | CustomerID_2 | ProductID | CreateDate | ArchiveFlag |
|--------------------------------------------------------------------------------
| 1          | 2          | 1            | 551       | 01-MAR-15  | F           |

回答1:


Oracle 12c introduced a row limiting clause and you could do (if you only want a single result):

SELECT *
FROM   customer c
       INNER JOIN purchase p
       ON ( c.customerid = p.customerid )
WHERE  p.archiveflag = 'F'
ORDER BY
       CreateDate DESC
FETCH FIRST 1 ROW ONLY

In earlier versions you can do:

SQL Fiddle

Oracle 11g R2 Schema Setup:

create table CUSTOMER(CustomerID INT);
create table PURCHASE(PurchaseID INT, CustomerID INT, ProductID INT, CreateDate date, ArchiveFlag char);

insert into CUSTOMER values(1);
insert into CUSTOMER values(2);

insert into PURCHASE values(1,1,443,'01-FEB-15','F');
insert into PURCHASE values(2,1,551,'01-MAR-15','F');
insert into PURCHASE values(3,1,151,'01-JAN-15','F');
insert into PURCHASE values(4,1,654,'01-MAY-15','T');
insert into PURCHASE values(5,1,345,'01-APR-15','T');
insert into PURCHASE values(6,2,234,'01-MAY-15','T');
insert into PURCHASE values(7,2,134,'01-APR-15','F');
insert into PURCHASE values(8,2,999,'01-JAN-15','F');
insert into PURCHASE values(9,2,724,'07-JUN-15','F');
insert into PURCHASE values(10,2,345,'01-JUN-15','T');

Query 1 - If you only want to get the latest for a single customer:

SELECT *
FROM   (
  SELECT *
  FROM   Purchase
  WHERE  archiveflag = 'F'
  AND    CustomerID = 1
  ORDER BY
         CreateDate DESC
)
WHERE ROWNUM = 1

Results:

| PURCHASEID | CUSTOMERID | PRODUCTID |              CREATEDATE | ARCHIVEFLAG |
|------------|------------|-----------|-------------------------|-------------|
|          2 |          1 |       551 | March, 01 2015 00:00:00 |           F |

Query 2 - If you want to get the latest for all customers:

SELECT PurchaseID,
       CustomerID,
       ProductID,
       CreateDate,
       ArchiveFlag
FROM   (
  SELECT p.*,
         ROW_NUMBER() OVER ( PARTITION BY p.CustomerID ORDER BY CreateDate DESC ) RN
  FROM   purchase p
  WHERE  ArchiveFlag = 'F'
)
WHERE  RN = 1

Results:

| PURCHASEID | CUSTOMERID | PRODUCTID |              CREATEDATE | ARCHIVEFLAG |
|------------|------------|-----------|-------------------------|-------------|
|          2 |          1 |       551 | March, 01 2015 00:00:00 |           F |
|          9 |          2 |       724 |  June, 07 2015 00:00:00 |           F |

If PURCHASE.CUSTOMERID is a not null foreign key linked to CUSTOMER.CUSTOMERID then you do not need to join the tables (as above).




回答2:


I think you want to use row_number():

select *
from customer c join
     (select p.*,
             row_number() over (partition by p.customerid order by p.createdate desc) as seqnum
      from purchase p
      where p.archiveflag = 'F'
     ) p
     on c.customerid = p.customerid and seqnum = 1;



回答3:


SQL Fiddle

Schema setup

create table CUSTOMER(CustomerID int)
create table PURCHASE(PurchaseID int, CustomerID int, ProductID int, CreateDate date, ArchiveFlag char)

insert into CUSTOMER values(1)
insert into CUSTOMER values(2)

insert into PURCHASE values(1,1,443,'01-FEB-15','F')
insert into PURCHASE values(2,1,551,'01-MAR-15','F')
insert into PURCHASE values(3,1,151,'01-JAN-15','F')
insert into PURCHASE values(4,1,654,'01-MAY-15','T')
insert into PURCHASE values(5,1,345,'01-APR-15','T')
insert into PURCHASE values(6,2,331,'01-FEB-15','T')
insert into PURCHASE values(7,2,298,'01-JUN-15','F')

Query to get latest pending for all customers

 select *
 from purchase pa join customer c on c.customerid=pa.customerid
   where pa.archiveflag = 'F'
   and pa.createdate=(select max(createdate) 
                      from purchase pb
                        where pa.customerid=pb.customerid
                        and pb.archiveflag='F')

Output

| PurchaseID | CustomerID | ProductID | CreateDate | ArchiveFlag | CustomerID |
|------------|------------|-----------|------------|-------------|------------|
|          2 |          1 |       551 | 2015-03-01 |           F |          1 |
|          7 |          2 |       298 | 2015-06-01 |           F |          2 |



回答4:


You can use top and order by in your query like this

select Top 1 *
from customer c
join purchase p
on c.customerid = p.customerid
and p.archiveflag = 'F' 
Order by p.CreateDate Desc;



回答5:


Just use where clause: as told you wanted purchase ID 2: do as below:

SELECT * FROM select * from customer c join purchase p on c.customerid = p.customerid and p.archiveflag = 'F'; order by CreateDate desc where PurchasedID = 2;




回答6:


Try this one..

select top 1 *
from customer c
join purchase p
on c.customerid = p.customerid
and p.archiveflag = 'F'
order by CreateDate desc;


来源:https://stackoverflow.com/questions/31609961/how-to-return-only-latest-record-on-join

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!