Oracle 11g:返回多行的子查询

时间:2013-07-23 04:35:21

标签: sql oracle oracle11g left-join

我有两张桌子

表-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  

我需要加入来自Bill_Date的{​​{1}}加入Bill_TableAccount_Num以及Serial_Num的{​​{1}}。

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

这是一个特殊情况,其中ACC1,001组合的版本号相同,所以我需要得到ACC1, 001 of Account_Table(即ROWNUM = 1)

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

预期结果:

ACC1, 001 of Bill_Table

我试过的查询是,

TOP 1

但是此查询会生成一个表格,该表格未显示我的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

任何帮助将不胜感激。

P.S:我做错的一件事是我只比较了与序列号ACC1, 001匹配的行。但是如果我删除这一行,那么我会得到更多的行。

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:1)

因为对于Account_Num = ACC1和serial_num = 001,表Bill_table有两行,Version_Num = 1,所以会发生两行。

并且未显示ACC3,因为您尚未执行LEFT OUTER JOIN。

以下是查询:

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

希望这有帮助。