sql - 在行之间随机排列一列

标签 sql oracle

如何有效地打乱大型(1m 到 5m 记录)表的内容?已知该列具有唯一值,但您可以假设为此目的删除了所有约束。我的头痛主要是因为我正在更新我选择的同一列。我的目标是使用 PL/SQL 做到这一点,以便我可以以编程方式执行其他操作,例如记录或更新其他表。

**Original table:**
+----+-----------+
| id | fname     |
+----+-----------+
|  1 | mike      |
|  2 | ricky     |
|  3 | jane      |
|  4 | august    |
|  6 | dave      |
|  9 | Jérôme    |
+----+-----------+

**Possible output:**
+----+-----------+
| id | fname     |
+----+-----------+
|  1 | dave      |
|  2 | jane      |
|  3 | mike      |
|  4 | ricky     |
|  6 | Jérôme    |
|  9 | august    |
+----+-----------+

我最近的尝试是创建一个使用 over (order by dbms_random.value) 的游标。并尝试根据 rownum 进行合并或更新。也许我可以通过创建各种临时表来绕过修改自我约束?我相当有信心 Oracle 有一些奇特的方法来做到这一点,但我的 SQL 能力仅限于基本的 CRUD 命令。

完整的解决方案在这里,基于戈登的回答:
merge into t
using (
select t.id, t2.name
from (select t.*, rownum as seqnum
      from t
     ) t join
     (select t.*, row_number() over (order by dbms_random.value) as seqnum
      from t
     ) t2
     on t.seqnum = t2.seqnum
) src
on (t.id = src.id)
when matched then update set t.name = src.name;

最佳答案

您可以使用随机行号进行自连接:

select t.id, t2.name
from (select t.*, row_number() over (order by dbms_random.value) as seqnum
      from t
     ) t join
     (select t.*, row_number() over (order by dbms_random.value) as seqnum
      from t
     ) t2
     on t.seqnum = t2.seqnum;

实际上,您不需要将两者都随机化:
select t.id, t2.name
from (select t.*, rownum as seqnum
      from t
     ) t join
     (select t.*, row_number() over (order by dbms_random.value) as seqnum
      from t
     ) t2
     on t.seqnum = t2.seqnum;

关于sql - 在行之间随机排列一列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41008985/

相关文章:

php - 从 PHP SQL 检查列为 NULL

oracle - 如何显示多个oracle中的前导零

Oracle 使用取自函数值的 like 比较

sql - Oracle SQL - 根据以前的记录填充列并将没有以前数据的记录保留为 NULL

oracle - Oracle 中的 "group by day"似乎没有按日期分组

sql - 迭代器的MySQL实现

php - PHP PDO如何在注册时对密码进行哈希处理,然后在登录时“取消哈希处理”

SQL Server DELETE 错误 - 子查询返回超过 1 个值

database - 使用虚拟列导出架构

mysql - 如何从fld_Date的引用字段中获取下一个日期字段?