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

Posted

技术标签:

【中文标题】如何将一个表中的随机值添加到另一个 Oracle SQL【英文标题】:How to add a random value from one table to another Oracle SQL 【发布时间】:2015-10-10 12:30:23 【问题描述】:

各位程序员们好

我现在被困住了。我有两个表,想将一个表中的随机值添加到另一个表中。 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 表就会失去它的价值 如果您知道解决方案,请帮助并感谢您的宝贵时间

干杯

【问题讨论】:

【参考方案1】:

您可以使用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 中使用散列,所以这有点推测。此外,除非您添加随机种子分配,否则这将是一个稳定的分配(意味着您每次都会得到相同的值)。

【讨论】:

问题是在执行 WHERE 子句后,SQL 会按位置对记录进行排序,只取随机记录的第一行。谢谢 12g 听起来不错,但是如果我们不使用 11g,我们有一位教授会惩罚我们。 @SandMan 。 . . order bykeepwhere 子句之后 执行。这个版本不应该有你的版本的问题(你的问题实际上是子查询中的order by不能保证按顺序返回任何东西,除了rownum的使用)。 我明白为什么我认为有错误。这是sql语句的问题。如果我声明 MIN(l.ID) 那么它将始终返回相同的 ID(这是最小值),因此每条记录都有相同的 l.ID。 @SandMan 。 . .这不是KEEP 的工作方式。如果您愿意,可以使用MAX()。聚合函数被DENSE_RANK 子句覆盖。 嗯,有些地方出了问题,因为住在纽约的每个用户都有相同的 ID,而住在迈阿密的每个用户都有相同的 ID,但与纽约不同。这与我的 SQL 遇到的错误相同。也不是因为我在刚刚检查的链接表中各有一条记录。【参考方案2】:

这是对 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 表中每条记录的表达式。

【讨论】:

以上是关于如何将一个表中的随机值添加到另一个 Oracle SQL的主要内容,如果未能解决你的问题,请参考以下文章

如何使用'$row'将一个数据库表中的特定值插入到另一个数据库表中?

如何从程序 oracle 中的表中随机打印?

如何将一个表中的值插入另一个表,然后更新原始表?

如何将一个表中的值插入到另一个表中?

在oracle中如何将一个表中所有数据加到另一个表中

如何将存储在引用表中的引用值插入到另一个表中?