如何将一个表中的随机值添加到另一个 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 by
和keep
在where
子句之后 执行。这个版本不应该有你的版本的问题(你的问题实际上是子查询中的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的主要内容,如果未能解决你的问题,请参考以下文章