如何将一个表中的随机值添加到另一个Oracle SQL

时间:2015-10-10 12:30:24

标签: sql oracle plsql oracle-sqldeveloper

你好其他程序员

我现在卡住了。我有两个表,并希望将一个表中的随机值添加到另一个表中。 Oracle语法使它变得不可能,无法找到另一种方法。两个表链接的唯一方法是通过名为location的列。我想将一个表中存在的随机ID添加到User表中。这是我到目前为止所提出的

UPDATE USERS u
SET LINK_ID = ( 
                SELECT s.ID FROM
                ( 
                  SELECT l.ID, l.location
                  FROM LINKS l
                  ORDER BY DBMS_RANDOM.value 
                ) s
                WHERE ROWNUM = 1
                AND UPPER(u.location) = UPPER(s.location)
              );

这是如此接近但尚未到来。这个解决方案的问题是在我按照位置运行AND UPPER(u.location) = UPPER(s.location) SQL命令后删除随机函数。

我甚至尝试将UPPER(u.location) = UPPER(s.location)移至

 ( 
   SELECT l.ID, l.location
   FROM LINKS l
   WHERE UPPER(u.location) = UPPER(l.location)
   ORDER BY DBMS_RANDOM.value 
 ) s

但是我得到一个错误:“U”。“LOCATION”:无效的标识符

因此,如果您创建了许多子查询,我猜U表会丢失其值 如果您知道解决方案,请帮助并感谢您的时间

干杯

2 个答案:

答案 0 :(得分:0)

您可以使用merge。但是使用您拥有的语法,您可以使用keep方法:

UPDATE USERS u
SET LINK_ID = (SELECT MIN(l.ID) KEEP (DENSE_RANK FIRST ORDER BY DBMS_RANDOM.value) 
               FROM LINKS l
               WHERE UPPER(u.location) = UPPER(l.location)
              );

这样,您就不需要额外的子查询,并且Oracle语法也可以。

注意:12g支持FETCH FIRST 1 ROW ONLY,这也消除了对子查询的需要。

编辑:

获取排序随机值的另一种方法是哈希:

UPDATE USERS u
SET LINK_ID = (SELECT MIN(l.ID) KEEP (DENSE_RANK FIRST ORDER BY ORA_HASH(l.location || l.ID)) 
               FROM LINKS l
               WHERE UPPER(u.location) = UPPER(l.location)
              );

注意:为了这个目的,我还没有在Oracle中实际使用哈希,所以这有点推测。此外,这将是一个稳定的分配(意味着您每次都会获得相同的值),除非您添加随机种子分配。

答案 1 :(得分:0)

这是对Gordon查询的修改,应该有效:

SET LINK_ID = (
    SELECT MIN(l.ID) 
           KEEP (DENSE_RANK FIRST ORDER BY DBMS_RANDOM.value || u.link_id ) 
    FROM LINKS l
    WHERE UPPER(u.location) = UPPER(l.location)
);

诀窍在于:ORDER BY DBMS_RANDOM.value || u.link_id

这可以防止Oracle优化查询,
因为它强制重新评估users表中每条记录的表达式。