2017-01-10 61 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;