0

我有两张桌子

表 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  

我需要通过加入and来获得Bill_Datefrom和。Bill_TableAccount_NumSerial_NumAccount_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两次。

输出:

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

任何帮助将不胜感激。

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

4

2 回答 2

3

这应该可以满足您的需要,使用LEFT JOINandROW_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

一个用于测试的 SQLfiddle

于 2013-07-23T04:50:24.307 回答
1

Two rows is happen because table Bill_table has two rows with Version_Num = 1 for Account_Num = ACC1 and serial_num = 001.

And ACC3 is not shown because you don't do LEFT OUTER JOIN yet.

Below is the query :

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

Hopefully this help.

于 2013-07-23T04:46:28.623 回答