oracle 如何通过以随机顺序重新定位值来更新列

hfyxw5xn  于 2023-02-11  发布在  Oracle
关注(0)|答案(3)|浏览(201)

好的,下面这个表格可以作为我正在处理的一个例子,这个表格由某人的名字和他们与其他人相比的顺序组成:
| 姓名|订单|
| - ------|- ------|
| ZAC|1个|
| 杰夫|第二章|
| 巴士|三个|
| 凯特|四个|
我的目标是按ORDER顺序取出数字,然后随机地重新定位它们,并将其更新到表中,同时将NAME记录保持在它们原来的位置。
所需结果的示例:
| 姓名|订单|
| - ------|- ------|
| ZAC|三个|
| 杰夫|1个|
| 巴士|四个|
| 凯特|第二章|
使用上表,我尝试了以下解决方案:

1

Update TEST_TABLE
Set ORDER = dbms_random.value(1,4);

这将产生1到4之间的随机数(包括1和4),但这些数字可以重复,因此ORDER可以多次使用相同的数字
尝试的解决方案示例:
| 姓名|订单|
| - ------|- ------|
| ZAC|三个|
| 杰夫|1个|
| 巴士|三个|
| 凯特|第二章|

2

Update TEST_TABLE
Set ORDER = (Select dbms_random.value(1,4) From dual);

这导致相同的随机数被复制到每个ORDER记录中,所以如果数字是3,那么它会将它们都更改为3。
尝试的解决方案示例:
| 姓名|订单|
| - ------|- ------|
| ZAC|三个|
| 杰夫|三个|
| 巴士|三个|
| 凯特|三个|
这是我第一次在StackOverflow上发帖,而且我对Oracle还比较陌生,所以希望我能正确地提出这个问题。

brccelvz

brccelvz1#

这个怎么样?
样本数据:

SQL> select * from test order by rowid;

NAME    C_ORDER
---- ----------
Zac           1
Jeff          2
Bart          3
Kate          4

根据row_number解析函数对数据进行随机排序得到的值更新表;通过rowid值找到匹配:

SQL> merge into test a
  2  using (with counter (cnt) as
  3          (select count(*) from test)
  4         select t.rowid rid,
  5                row_number() over(order by dbms_random.value(1, c.cnt)) rn
  6         from counter c cross join test t
  7        ) b
  8  on (a.rowid = b.rid)
  9  when matched then update set
 10    a.c_order = b.rn;

4 rows merged.

结果:

SQL> select * from test order by rowid;

NAME    C_ORDER
---- ----------
Zac           3
Jeff          4
Bart          1
Kate          2

SQL>
5lwkijsr

5lwkijsr2#

这个怎么样?

MERGE INTO test d USING
  (SELECT rownum AS new_order,
          name
     FROM (SELECT *
             FROM test
            ORDER BY dbms_random.value)) s
   ON (d.name = s.name)
 WHEN matched THEN
   UPDATE
     SET d.sort_order = s.new_order;

新的顺序是通过简单地按随机值对原始数据排序并使用rownum对这些随机记录从1到N进行编号来建立的。
我使用NAME来匹配记录,但是您应该使用主键或rowid,就像Littlefoot answer中那样,或者至少使用一个索引列(为了速度起见,当表包含大量数据时),它唯一地标识一行。

tyu7yeag

tyu7yeag3#

最简单的方法是对数据进行随机排序,然后在“name”列上进行联接:

merge into data dst 
using (
    select rownum as rn, name from (
        select name from data order by dbms_random.value()
    )
) src
on (src.name = dst.name)
when matched then
    update set ord = src.rn 
;

相关问题