如何仅返回加入的最新记录

时间:2015-07-24 11:56:16

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

我加入了桌子。我只想根据日期字段从连接表中返回一条记录。

这是我到目前为止所做的简化:http://sqlfiddle.com/#!3/be0cdd/2

我的桌子:

  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           |

以及查询本身:

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

我只想为每位客户退回尚未存档的最新购买(在此示例中为购买ID 2)。

理想输出:

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

6 个答案:

答案 0 :(得分:3)

Oracle 12c引入了行限制子句,您可以这样做(如果您只想要一个结果):

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

在早期版本中,您可以这样做:

SQL Fiddle

Oracle 11g R2架构设置

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');

查询1 - 如果您只想获得单个客户的最新信息

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 |

查询2 - 如果您想获取所有客户的最新信息

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 |

如果PURCHASE.CUSTOMERID是与CUSTOMER.CUSTOMERID关联的非空外键,则您不需要加入表格(如上所述)。

答案 1 :(得分:1)

我认为你想使用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;

答案 2 :(得分:1)

SQL Fiddle

架构设置

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')

查询以获取所有客户的最新待处理

 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')

<强>输出

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

答案 3 :(得分:-1)

您可以在查询中使用top和order by,如下所示

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

答案 4 :(得分:-1)

只需使用where子句:如您所知,购买ID 2:执行如下操作:

SELECT * FROM     选择 *     来自客户c     加入购买     在c.customerid = p.customerid     和p.archiveflag ='F';     按CreateDate desc排序     其中,PurchasedID = 2;

答案 5 :(得分:-1)

试试这个......

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