为每一行选择随机值

时间:2018-06-26 05:09:27

标签: sql oracle random

假设我有2个表,分别名为“ FOR_TEST_1”和A,B,C列,以及“ FOR_TEST_2”,其D,E,F列。

我想生成与列D中的随机值配对的列A。

这是表格的摘录。

Table FOR_TEST_1

Table FOR_TEST_2

到目前为止,这是我一直在执行的语句,它为A中的每一行返回相同的D值。

Query result

目前,我正在使用toad for oracle,但我尝试在MySQL中使用相同的逻辑,并且效果很好。

2 个答案:

答案 0 :(得分:1)

您期望Oracle每行执行一次子查询(这是MySQL所做的)。但是,您似乎已经遇到了Oracle优化的副作用。主查询和标量子查询之间没有关联,因此Oracle决定取消嵌套该子查询,执行一次,然后将结果加入主查询。

要获得结果,您需要几个选择。一种是用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演示(find it here)。不知道为什么,语法看起来正确。因此,请在您的环境中尝试使用该方法,或者只使用第二种方法,该方法肯定有效。

答案 1 :(得分:0)

尝试一下:

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