我有两个没有公共(public)键的表,我想在这两个表上进行连接而不使用笛卡尔连接。 表 1 大约有 40,000 行(记录数量因每天生产而变化),而表 2 目前的数量为 80,000 行(记录数量因每天生产而变化)。
表 1:- NAME_VALUES
NAME_VAL
--------
TOM
DICK
HARRY
表2:- CUS_TABLE
CUS_ID
---------
401795480
201134211
137643082
876450821
777290153
111035791
579865552
我想要像下面这样的东西作为输出
401795480 TOM
201134211 DICK
137643082 HARRY
876450821 DICK
777290153 HARRY
111035791 TOM
579865552 DICK
我的想法是为每个表分配行号。对于表 2,一旦达到表 1 的最大计数,我想重新启动行号,如下所示,但无法弄清楚如何执行
Table1
NAME_VAL TABLE1_RN
---------------------
TOM 1
DICK 2
HARRY 3
Table2
CUS_ID TABLE2_RN
--------------------
401795480 1
201134211 2
137643082 3
876450821 1
777290153 2
111035791 3
579865552 1
现在我有了一把 key ,可以轻松映射以获取我需要的详细信息。
请提出是否有任何方法可以满足我的要求。
最佳答案
展示想法的规范(可能很慢)解决方案
这是一个在连接谓词上使用模运算符的相当慢的解决方案:
SELECT cus_id, name_val
FROM (
SELECT cus_id, ROWNUM - 1 rn
FROM cus_table
) c
JOIN (
SELECT name_val, ROWNUM - 1 rn, MAX(ROWNUM) OVER() total
FROM name_values
) n
ON n.rn = MOD(c.rn, n.total)
ORDER BY c.rn
以上产量
CUS_ID NAME_VAL
--------------------
401795480 TOM
201134211 DICK
137643082 HARRY
876450821 TOM
777290153 DICK
111035791 HARRY
579865552 TOM
使用 SQL 更快的解决方案
为了加快上述速度,您有多种选择,包括为 c
和 n
创建物化 View ,或预先计算 n 的值.rn - 1
和 MOD(c.rn - 1, n.total)
在源表中,同时在这些预先计算的表上放置索引。
使用 PL/SQL 更快的解决方案
如果您被允许在系统中编写 PL/SQL,那么您显然可以使用 PIPELINED
函数来实现此目的:
CREATE TYPE rec AS OBJECT (
cus_id NUMBER(18),
name_val VARCHAR2(50)
);
/
CREATE TYPE tab AS TABLE OF rec;
/
CREATE OR REPLACE FUNCTION f RETURN tab PIPELINED AS
TYPE name_vals IS TABLE OF name_values.name_val%type;
v_name_vals name_vals;
BEGIN
SELECT name_val
BULK COLLECT INTO v_name_vals
FROM name_values;
FOR cus IN (SELECT cus_id, ROWNUM rn FROM cus_table)
LOOP
PIPE ROW(rec(cus.cus_id, v_name_vals(MOD(cus.rn - 1, v_name_vals.count) + 1)));
END LOOP;
RETURN;
END;
/
然后按如下方式使用该函数:
SELECT * FROM TABLE(f);
关于sql - 根据oracle sql中其他表中的计数重新启动行号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34704821/