Выбор случайного значения для каждой строки - PullRequest
0 голосов
/ 26 июня 2018

Предположим, у меня есть 2 таблицы с именем 'FOR_TEST_1' со столбцами A, B, C и 'FOR_TEST_2' со столбцами D, E, F.

Я хотел бы создать столбец A в паре со случайным значением изстолбец D.

Вот фрагмент таблицы.

Table FOR_TEST_1

Table FOR_TEST_2

Пока что это утверждение, которое я делал, и оно возвращает одинаковое значение D для каждой строки в A.

Query result

В настоящее время я использую жабу для оракула, но я пытался использовать ту же логику в MySQL, и она отлично работает.

Ответы [ 2 ]

0 голосов
/ 26 июня 2018

Вы ожидаете, что Oracle выполнит подзапрос один раз в строке (что и делает MySQL).Однако, похоже, вы столкнулись с побочным эффектом оптимизации Oracle.Нет корреляции между основным запросом и скалярным подзапросом, поэтому Oracle решает разложить вложенный запрос, выполнить его один раз и присоединить результат к основному запросу.

Чтобы получить требуемые результаты, у вас есть параопции.Одним из них является отключение unnesting с подсказкой NO_UNNEST.

select   t1.a
       ,  ( select d from ( select /*+ NO_UNNEST */  d from for_test_two 
            order by dbms_random.value ) where rownum = 1) d
from for_test_one t1
/

В качестве альтернативы вы можете переписать свой запрос для использования встроенного представления, а не скалярного подзапроса.

select t1.a
       , t2.d
from ( select a, rownum as rn 
        from for_test_one) t1
     join ( select d, rownum as rn 
         from ( select d from for_test_two 
                order by dbms_random.value() ) ) t2
     on t1.rn = t2.rn
order by t1.rn
/

Предупреждение : NO_UNNESTРешение не работает на демонстрации SQL Fiddle ( найдите его здесь ).Не уверен, почему, синтаксис выглядит правильно.Попробуйте это в своей среде или просто используйте второй подход, который определенно работает.

0 голосов
/ 26 июня 2018

Попробуйте это:

SELECT A, (SELECT D (
           SELECT D, ROWNUM ROWPTR FROM FOR_TEST_2)
           WHERE ROWPTR = (SELECT ROUND(DBMS_RANDOM.VALUE(1, (SELECT COUNT(D) FROM FOR_TEST_2) + 1 )) from DUAL)) D 
FROM FOR_TEST_1 
...