2017-01-10 21 views
0

我的表在內部枚舉行加入

id name num 
1 a 3 
2 b 4 

我需要返回的時候每一行NUM數。我這樣做。

select DB.BAN_KEY as BAN_KEY, DB.CUST_FULLNAME as CUST_FULLNAME 
    from TST_DIM_BAN_SELECTED DB 
    inner join (select rownum rn from dual connect by level < 10) a 
    on a.rn <= DB.N 

結果表看起來像這樣。

id name 
1 a 
1 a 
1 a 
2 b 
2 b 
2 b 
2 b 

但我也需要組中的每一行都像這樣編號。

id name row_num 
1 a 1 
1 a 2 
1 a 3 
2 b 1 
2 b 2 
2 b 3 
2 b 4 

我該怎麼辦?

回答

1

你不需要

Select id, name, 
row_number() over (partition by id, name order by id, name) 
From(/* your query */) t; 

這可以在沒有子查詢完成對虛擬表或分析函數的內部連接以生成行號;你可以只用通過對錶本身連接(及其相應級別的功能),像這樣:

WITH tst_dim_ban_selected AS (SELECT 1 ban_key, 'a' cust_fullname, 3 n FROM dual UNION ALL 
           SELECT 2 ban_key, 'b' cust_fullname, 4 n FROM dual) 
-- end of mimicking your table with data in it. See SQL below 
SELECT db.ban_key, 
     db.cust_fullname, 
     LEVEL row_num 
FROM tst_dim_ban_selected db 
CONNECT BY LEVEL <= db.n 
      AND PRIOR db.ban_key = db.ban_key -- assuming this is the primary key 
      AND PRIOR sys_guid() IS NOT NULL; 

    BAN_KEY CUST_FULLNAME ROW_NUM 
---------- ------------- ---------- 
     1 a      1 
     1 a      2 
     1 a      3 
     2 b      1 
     2 b      2 
     2 b      3 
     2 b      4 

如果您有其他的列比在表的主鍵ban_key,你需要確保它們被包含在連接條款的列表prior <column> = <column> s。這是通過連接可以唯一地識別每一行,這意味着它正在循環而不是其他人。需要PRIOR sys_guid() IS NOT NULL以防止發生循環連接。

1

您可以使用分析功能是:

Select id, name, 
row_number() over (partition by id, name order by id, name) 
From /* joins */ 
0

您可以使用此:

SELECT db.ban_key AS ban_key, db.cust_fullname AS cust_fullname, 
    ROW_NUMBER() OVER (PARTITION BY db.n ORDER BY db.ban_key) AS row_num 
FROM tst_dim_ban_selected db 
INNER JOIN (SELECT rownum rn FROM dual CONNECT BY level < 10) a 
ON a.rn <= db.n; 
0

使用遞歸子查詢保條款:

WITH split (id, name, rn, n) AS (
    SELECT BAN_KEY, CUST_FULLNAME, 1, N 
    FROM TST_DIM_BAN_SELECTED 
UNION ALL 
    SELECT id, name, rn + 1, n 
    FROM split 
    WHERE rn < n 
) 
SELECT id, name, rn 
FROM split;