2

次のようなテーブルがあります

id| page |   text
------------------------
1 | page1 | Hello World
2 | page1 | Foo Bar
3 | page2 | Baz Baz
3 | page2 | Some Text
4 | page3 | Some Other Text

2 つのランダムなエントリを選択したいのですが、各ページは結果に 1 回しか表示されません。

私は持っている

SELECT * FROM mydata ORDER BY RANDOM(); リミット 2

DISTINCTしかし、これをまたはグループ化と組み合わせることはできますか?

4

4 に答える 4

2

何かのようなもの:

select id, page, text
from (
  select id, page, text,
         row_number() over (partition by page order by random()) as rn
  from mydata
) 
where rn <= 2
于 2012-08-24T21:04:55.443 に答える
1

必要な場合:
... ベース テーブルから合計 2 行
... そして、テーブル内のエントリ数に関係なく、すべてのページがサンプルに表示される機会を均等にします。

SELECT *
FROM  (
    SELECT DISTINCT ON (page) *
    FROM   mydata
    ORDER  BY page, random() -- pick one random entry per page
    ) x
ORDER BY random() -- pick two random pages
LIMIT 2;

または、ウィンドウ関数を使用すると、次のようになります。

WITH x AS (
   SELECT *, row_number() OVER (PARTITION BY page ORDER BY random()) AS rn
   FROM   mydata
   )
SELECT id, page, text
FROM   x
WHERE  rn = 1
ORDER  BY random()
LIMIT  2;

どちらが速いかをテストする必要があります。
大きなテーブルを扱っていて、高速なパフォーマンスが必要な場合は、より良い結果が得られます。これが方法の1つです。


一方、必要な場合:
... テーブルから合計 2 行mydata
...すべてのエントリに (ほぼ) 均等にサンプルに表示される機会を与え、より多くのエントリを持つページにより良い機会を効果的に与えます。テーブルで。
チャンスはまだ真に等しいわけではありません - あなたの制限は定義上、まれなページのエントリのチャンスを増やします.

WITH x AS (
   SELECT *
   FROM   mydata
   ORDER  BY random()
   LIMIT 1
   )
SELECT * FROM x
UNION ALL
(
SELECT m.*
FROM mydata m
   , x
WHERE m.page <> x.page -- assuming page IS NOT NULL
ORDER BY random()
LIMIT 1
);

SELECTの 2 番目を囲む括弧は、UNION個別の注文を可能にするために必要です。
PostgreSQL 9.1 でテスト済み。ウィンドウ関数には、バージョン 8.4 以降が必要です。

于 2012-08-25T02:03:59.363 に答える
1

アーウィンの答えと同じですが、少し構造化されています: http://www.sqlfiddle.com/#!1/d3e83/6

with first_random as
(
  select * from tbl order by random() limit 1
)
, second_random as
(
  select * 
  from tbl 
  where page <> (select page from first_random)
  order by random() limit 1
)
select * from first_random
union
select * from second_random;

a_horse_with_no_name の答えと同じですが、これが正しいことを除いて: http://www.sqlfiddle.com/#!1/d3e83/12

select id, page, text, rn
from (
  select id, page, text,
         row_number() over (partition by page order by random()) as rn
  from tbl
) x
where rn = 1
order by random() 
limit 2;

後者を選択すると、より単純な実行計画があります

于 2012-08-25T02:16:22.810 に答える
0

それはうまくいくかもしれません:

SELECT * FROM
  (SELECT * FROM mydata GROUP BY page) t
ORDER BY RANDOM() LIMIT 2
于 2012-08-27T09:43:00.950 に答える