Sql oracle中的随机连接
我有三个查询,我希望结果行由这些查询的条目组成,这些条目彼此随机连接 我不想合并结果,而是以或多或少的随机方式将它们合并(原始分布可以保留,也可以在所有结果中统一) 我尝试了以下方法:Sql oracle中的随机连接,sql,oracle,join,random,Sql,Oracle,Join,Random,我有三个查询,我希望结果行由这些查询的条目组成,这些条目彼此随机连接 我不想合并结果,而是以或多或少的随机方式将它们合并(原始分布可以保留,也可以在所有结果中统一) 我尝试了以下方法: select * from ( SELECT street, number FROM Addresses WHERE valid = '1' order by Dbms_Random.Value ) q1 , ( select prename from
select *
from
(
SELECT street, number
FROM Addresses
WHERE valid = '1'
order by Dbms_Random.Value
) q1 ,
(
select prename
from person
order by Dbms_Random.Value
) q2 ,
(
select surname
from person
order by Dbms_Random.Value
) q3
然而,我的结果集看起来一点也不随机:
Main street, 1, Andre, Smith
Main street, 1, Andre, Warnes
Main street, 1, Andre, Jackson
Main street, 1, Andre, Macallister
从查询中删除
ORDER BY
并将其应用于笛卡尔乘积的结果是非常低效的,因为表非常大,尤其是它们的笛卡尔乘积。您遇到的问题是,虽然每个表都是随机排序的,您仍然有一个笛卡尔乘积,这样顶部行的前两列的值相同,而最后一列的值不同
如果选择伪列ROWNUM(需要将其别名为eg row_number),然后在row_number上连接3个表,那么应该从3个表中获得数据的随机组合
但总行数将被限制为与最小表中的行数相等。您可以将Dbms_Random.Value移动到子查询中的一列,并用它连接。
这将使结果随机化,并通过消除
顺序:
select *
from
(
SELECT street, snumber, ROUND(Dbms_Random.Value(1,10)) n
FROM Addresses
WHERE valid = '1'
) q1 ,
(
select prename, ROUND(Dbms_Random.Value(1,10)) n
from person
) q2 ,
(
select surname, ROUND(Dbms_Random.Value(1,10)) n
from person
) q3
where q1.n = q2.n
and q2.n = q3.n
;
(另见)
ROUND(Dbms_Random.value(1,10))
中的值10
只是一个假设,请将其更改为预期或可用记录的数量
请注意,此解决方案重用每个子查询的结果,因此,例如,prename可能会被多次使用或根本不使用,但在原始笛卡尔联接中也是如此。
确保唯一性,如果您需要的话。科林·哈特诊断了这个问题,并建议使用rownum解决问题。但解决方案比这稍微复杂一些,因为如果ROWNUM和ORDER BY都出现在同一个SELECT中,则会在ORDER BY之前指定它们。解决方案是添加一个额外的子查询级别
with randomAddress as(
select rownum id, street, num from (
select * from addresses where valid=1 order by dbms_random.random
)
),
randomPrename as(
select rownum id, prename from(
select * from person order by dbms_random.random
)
),
randomSurname as(
select rownum id, surname from(
select * from person order by dbms_random.random
)
)
select street, num, prename, surname
from randomAddress
join randomPrename using(id)
join randomSurname using(id)
;
此解决方案将始终返回与最小表中的行数相等的随机行数。任何行都不会被多次使用。这是你的电话号码
GWu解决方案返回的行数将根据分配给相同随机数的行数而有所不同。某些行可能会被多次使用,而其他行则根本不会。您还应该知道表中有多少行可以使用该解决方案。目前您正在检索笛卡尔积。这就是你想要的吗?比如,如果每个表有10行,那么您是否希望结果集以随机顺序包含所有1000个连接行?还是只需要10行?要查找多少值?每张桌子有多大?谢谢你的回答。结果总数不应该是笛卡尔积的大小,而可以是最小表和最大表之间的某个地方。一个选项卡中的行可以多次出现。+1,但解决方案比您描述的要复杂一些。请参阅,OP需要澄清他是否希望值只使用一次。返回的行数是随机的。从理论上讲,这种解决方案有时可能不会返回任何行,尽管这是一种极低的风险,除非随机数限制远远大于最小表中的行数。