1

3つのクエリがあり、これらのクエリのエントリで構成される結果行をランダムに並べて結合したいと考えています。

結果を結合したくはありませんが、多かれ少なかれランダムな方法で結果を結合します(元の分布を維持することも、すべてに統合することもできます)。

私は次のことを試しました:

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てデカルト積の結果に適用することは、テーブルが大きく、特にデカルト積であるため、非常に非効率的です。

4

3 に答える 3

5

Colin't Hartは問題を診断し、rownumを使用する回避策を提案しました。ただし、両方が同じSELECTに表示される場合、ROWNUMはORDER BYの前に割り当てられるため、ソリューションは少し複雑になります。解決策は、サブクエリレベルを1つ追加することです。

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)
;

このソリューションは常に、最小のテーブルの行数に等しい数のランダムな行を返します。行が複数回使用されることはありません。これがSQLフィドルです。

GWuソリューションによって返される行の数は、同じ乱数が割り当てられている行の数によって異なります。一部の行は複数回使用される場合があり、他の行はまったく使用されない場合があります。また、そのソリューションを使用するには、テーブルにいくつの行があるかについても知っておく必要があります。

于 2012-07-24T16:37:01.310 に答える
3

Dbms_Random.Valueをサブクエリの列に移動し、それによって結合することができます。
これにより、結果がランダム化され、order by:も削除されます。

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
;

http://www.sqlfiddle.com/#!4/a26d0/9も参照してください)

の値10ROUND(Dbms_Random.Value(1,10))単なる仮定であり、予想されるレコードまたは使用可能なレコードの数に変更してください。

このソリューションは各サブクエリの結果を再利用するため、たとえばprenameが複数回使用されるか、まったく使用されない場合がありますが、これは元のデカルト結合にも当てはまります。
コリンのアプローチは、必要に応じて独自性を保証します。

于 2012-07-24T16:15:36.767 に答える
2

あなたが抱えている問題は、各テーブルがランダムに並べられている間、あなたはまだデカルト積を持っているので、一番上の行は同じ値を持つ最初の2列を持ち、最後の列だけが異なるということです。

疑似列ROWNUMを選択し(たとえば、row_numberとしてエイリアス化する必要があります)、次にrow_numberで3つのテーブルを結合すると、3つのテーブルからデータのランダムな組み合わせを取得する必要があります。

ただし、最小のテーブルの行数に等しい行の総数に制限されます。

于 2012-07-24T15:17:42.937 に答える