我有一个表,其中的列包含一些值。我想用另一个表中的随机值替换所有现有值(但仅替换现有值-WHERE COL1 IS NOT NULL
)。无法关联这两个表。每个随机值都必须不同(嗯...除非它们随机地相同,在这种情况下就可以了)。
例如:
CREATE TABLE T1 (ID NUMBER(11,0), COL1 VARCHAR2(20));
CREATE TABLE T2 (COL2 VARCHAR2(20));
INSERT INTO T1 VALUES (1, NULL);
INSERT INTO T1 VALUES (54, NULL);
INSERT INTO T1 VALUES (941, 'Some text');
INSERT INTO T1 VALUES (251, NULL);
INSERT INTO T1 VALUES (352, 'Some other text');
INSERT INTO T1 VALUES (354, NULL);
INSERT INTO T2 VALUES ('Val1');
INSERT INTO T2 VALUES ('Val2');
INSERT INTO T2 VALUES ('Val3');
INSERT INTO T2 VALUES ('Val4');
INSERT INTO T2 VALUES ('Val5');
INSERT INTO T2 VALUES ('Val6');
INSERT INTO T2 VALUES ('Val7');
我尝试了一些操作,并在此站点上搜索了答案。我发现的答案似乎要求两个表之间有一定的相关性。许多示例都是针对SQL Server的。无论如何,我都尝试了一些,但是似乎无法获得MERGE
或CROSS APPLY
的工作方式(我很欣赏这很可能是我的失败...)。
目前,我唯一实际可行的解决方案是:
BEGIN
FOR X IN (
SELECT ID FROM T1 WHERE COL1 IS NOT NULL
)
LOOP
UPDATE T1 SET COL1 = (
SELECT COL2 FROM (
SELECT COL2 FROM T2 ORDER BY SYS_GUID()
) WHERE ROWNUM = 1
)
WHERE T1.ID = X.ID;
END LOOP;
END;
/
这将产生(期望的)结果:
SELECT * FROM T1;
ID COL1
---------------------------
1
54
941 Val3
251
352 Val7
354
(每次运行循环时,COL1值都是随机的。)
...但是我知道 必须 是一种基于集合的方法来实现这一目标...对吗?
答案 0 :(得分:2)
您可以使用MERGE语句来实现。
merge into t1
using ( select a1.id
, a2.col2
from ( select id
, row_number() over (order by dbms_random.value) rn
from t1
where col1 is not null ) a1
join ( select col2
, row_number() over (order by dbms_random.value) rn
from t2) a2
on a1.rn = a2.rn
) q
on ( q.id = t1.id)
when matched then
update set t1.col1 = q.col2
/
USING查询有点不合常规。有两个子查询,每个子查询一个,以随机顺序生成分析row_number()
(这比使用rownum
更为简洁。这两个子查询在随机行号上连接在一起,给出了以下项的随机组合) T1.ID和T2.COL_2。之后,这是一个简单的合并。
答案 1 :(得分:1)
您可以创建一个名为GET_RANDOM_VALUE的功能
create or replace FUNCTION GET_RANDOM_VALUE
RETURN VARCHAR2 AS
sValue VARCHAR2(100) := '?';
BEGIN
select col2 INTO sValue
from t2
order by dbms_random.value
fetch first 1 rows only;
RETURN sValue;
END GET_RANDOM_VALUE;
和UPDATE命令可以
UPDATE t1
SET col1 = GET_RANDOM_VALUE()
WHERE col1 IS NOT NULL;
通常,我避免在函数中使用SELECT,但是在这种情况下,我发现此解决方案更易读且更易于理解。