Как обновить столбец, переставив значения в случайном порядке

Итак, эта таблица будет служить примером того, с чем я работаю. Эта таблица состоит из имени кого-то и порядка, в котором они находятся по сравнению с другими:

ИМЯ ЗАКАЗ ЗАК 1 ДЖЕФФ 2 БАРТ 3 КАТЯ 4

Моя цель состоит в том, чтобы взять числа в ORDER и переставить их случайным образом и обновить это в таблице, сохраняя записи NAME в том же положении, в котором они были изначально.

Пример желаемого результата:

ИМЯ ЗАКАЗ ЗАК 3 ДЖЕФФ 1 БАРТ 4 КАТЯ 2

Используя приведенную выше таблицу, я пробовал следующие решения:

#1

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

Это привело к случайным числам от 1 до 4 включительно, но числа могли повторяться, поэтому ORDER мог иметь одно и то же число несколько раз.

Пример попытки решения:

ИМЯ ЗАКАЗ ЗАК 3 ДЖЕФФ 1 БАРТ 3 КАТЯ 2

#2

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

Это привело к тому, что одно и то же случайное число было скопировано в каждую запись ORDER, поэтому, если получилось число 3, оно изменит их все на 3.

Пример попытки решения:

ИМЯ ЗАКАЗ ЗАК 3 ДЖЕФФ 3 БАРТ 3 КАТЯ 3

Это моя первая публикация в StackOverflow, и я относительно новичок в Oracle, поэтому, надеюсь, я правильно задал этот вопрос.

Не могли бы вы сообщить нам, что вы подразумеваете под «сохранением записей NAME в том же положении, в котором они были изначально». данные возвращаются запросом или так они хранятся в БД. В Oracle, если вы хотите, чтобы данные отображались, всегда лучше указать предложение ORDER BY, а также данные не хранятся в каком-либо определенном порядке в БД.

Himanshu Kandpal 11.02.2023 01:57

@HimanshuKandpal Может быть, это была плохая формулировка с моей стороны. Я имел в виду, что хотел только обновить значения в ORDER. Новые значения должны быть случайным числом от 1 до 4, и это число не может быть одинаковым в разных строках. Необходимо обновить только столбец ORDER, а не столбец NAME.

Z___ 11.02.2023 02:35

Что такое первичный ключ в таблице? НАЗВАНИЕ, ПОРЯДОК, НАЗВАНИЕ и ПОРЯДОК или что-то другое?

Jon Heller 11.02.2023 06:32

@JonHeller Мне нужно было просто использовать идентификатор вместо имени для примера, но для простоты имя будет pk в этом примере

Z___ 14.02.2023 18:58
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
0
4
70
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Как насчет этого?

Образец данных:

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>
Ответ принят как подходящий

Как насчет этого?

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. Или хотя бы индексированный столбец (для скорости, когда в таблице много данных), который однозначно идентифицирует строку.

В реальной таблице, с которой я работаю, у нее есть pk, который я использую, и я должен был поместить его вместо имени в примере. Но это, кажется, решает мою проблему. Вы, ребята, все потрясающие!

Z___ 14.02.2023 19:01

Самый простой — отсортировать данные случайным образом и объединить их в столбце «имя»:

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 
;

Другие вопросы по теме