2013-07-23 45 views
0

我有两个表的Oracle 11g:子查询返回多个行

表1:Account_Table

Account_Num | Serial_Num | Transaction_Date | Balance | Frequency 
    ACC1   001   Date1   0   f1 
    ACC1   002   Date2   1   f2 
    ACC1   003   Date3   2   f3 

表-2:Bill_Table

Account_Num | Serial_Num | Version_Num | Bill_Date 
    ACC1   001   1   Date1 (say) 
    ACC1   002   1   Date2 
    ACC1   001   1   Date3 

我需要通过加入Account_Num和从Bill_Table获得Bill_Date两者都是Account_TableBill_Table的。

如果Bill_Table与Account_Num,Serial_Num有多个行匹配。这是ACC1, 001 of Account_Table与两行ACC1, 001 of Bill_Table相匹配的情况,那么我需要获取相应Account_Num,Serial_Num组合的最大版本号并返回该行的Bill_Date。

这是版本号是相同的两个ACC1,001组合的特殊情况,所以我需要获得TOP 1(即ROWNUM = 1)

示例:Account_Table具有3行。现在我的输出应该

预期的结果:表

Account_Num | Serial_Num | Bill_Date 
    ACC1   001   Date 
    ACC1   002   Date 
    ACC1   003   null 

查询,我已经试过是,

SELECT 
      A.ACCOUNT_NUM, 
      A.SERIAL_NUM, 
      B.BILL_DATE 
    FROM ACCOUNT_TABLE A, BILL_TABLE B WHERE 
     A.ACCOUNT_NUM = 'ACC1' AND 
     B.ACCOUNT_NUM = 'ACC1' AND 
     A.SERIAL_NUM = B.SERIAL_NUM AND  
     B.VERSION_NUM = (SELECT MAX (BIV.VERSION_NUM) FROM BILL_TABLE BIV 
            WHERE BIV.ACCOUNT_NUM = 'ACC1' 
            AND BIV.SERIAL_NUM = B.SERIAL_NUM 
         ); 

但这个查询结果不显示我的ACC1, 003组合ACC1, 001两次。

OUTPUT:

ACCOUNT_NUM | SERIAL_NUM | BILL_DATE 
    ACC1   001   Date 
    ACC1   001   Date 
    ACC2   002   Date 

任何帮助将不胜感激。

P.S:我做错了的一件事是我只比较与序列号A.SERIAL_NUM = B.SERIAL_NUM相匹配的行。但是,如果我删除这条线,那么我得到更多的行。

回答

3

这应该做你所需要的,使用LEFT JOINROW_NUMBER()找到正确的版本;

SELECT account_num, serial_num, version_num, bill_date 
FROM (
    SELECT a.account_num,a.serial_num,b.version_num,b.bill_date, 
    ROW_NUMBER() OVER (PARTITION BY a.account_num, a.serial_num 
         ORDER BY b.version_num DESC) rn 
    FROM account_table a 
    LEFT JOIN bill_table b 
    ON a.account_num = b.account_num 
    AND a.serial_num = b.serial_num 
) 
WHERE rn=1 

An SQLfiddle to test with

+0

+1真棒。请给我一些时间来测试其他案件。我相信它会起作用。 – Amarnath

+0

有趣! ROW_NUMBER()对我来说是新的,因为我上次在2010年使用了oracle。您有我的投票,Joachim。 :) –

+0

Sry我的错误..其工作正常。 – Amarnath

1

两排发生,因为表Bill_table有没有显示,因为你不这样做LEFT OUTER JOIN但两行VERSION_NUM = 1 ACCOUNT_NUM = ACC1和SERIAL_NUM = 001

和ACC3。

下面是查询:

SELECT A.ACCOUNT_NUM, A.SERIAL_NUM, B.VERSION_NUM, B.BILL_DATE 
FROM ACCOUNT_TABLE A 
LEFT OUTER JOIN 
(
    SELECT ACCOUNT_NUM, SERIAL_NUM, VERSION_NUM, BILL_DATE 
    FROM (
     SELECT ACCOUNT_NUM, SERIAL_NUM, VERSION_NUM, BILL_DATE, 
     MAX(VERSION_NUM) OVER (PARTITION BY ACCOUNT_NUM, SERIAL_NUM) AS MAX_VERSION_NUM, 
     MAX(BILL_DATE) OVER (PARTITION BY ACCOUNT_NUM, SERIAL_NUM, VERSION_NUM) AS MAX_BILL_DATE 
     FROM BILL_TABLE 
    ) WHERE VERSION_NUM = MAX_VERSION_NUM AND BILL_DATE = MAX_BILL_DATE 
) B ON B.ACCOUNT_NUM = A.ACCOUNT_NUM AND B.SERIAL_NUM = A.SERIAL_NUM 

希望这帮助。

+0

+1是的。我曾尝试使用左外连接也..但我仍然无法获得预期的结果 – Amarnath

+0

Hi Che,更新了我对查询的回答。 –