3

次の 3 つのデータ テーブルがあります。

table: cars    [10,000 rows]
table: planes  [2,000 rows]
table: trains  [50 rows]

次のような 3 つのテーブルから取得したデータのページをユーザーに表示できるようにしたいと考えています。

car
plane
train
car
plane
train
...

ポイントは、各テーブルが使い果たされるまで、各タイプの 1 つを見て、ページングを続けることができるということです。たとえば、ある時点で、飛行機と列車のテーブルが車のテーブルよりも先に使い果たされるため、各ページには車のみが含まれます。

制限に達するまで、各テーブルから 1 行を取得するために実行できるクエリはありますか? 何かのようなもの:

SELECT * FROM cars, planes, trains ORDER BY (natural row ordering?) LIMIT 20;

これを行う唯一の方法は、1 つのマスター テーブルを作成し、挿入するときに各行にダミーの整数を割り当てることです。

  id |  type  | description | dummy_integer
--------------------------------------------
 ...    car     ...             0
 ...    plane   ...             1
 ...    train   ...             2
 ...    car     ...             3
 ...    plane   ...             4
 ...    train   ...             5
 ...    ...     ...             ...
 ...    car     ...             8000
 ...    car     ...             8001
 ...    car     ...             8002
 ...    ...     ...             ...

それから私はすることができます:

SELECT * FROM master_table ORDER BY dummy_integer ASC LIMIT 20;

ページングは​​、最後に見た dummy_integer を使用して行われます。

SELECT * FROM master_table WHERE dummy_integer > 20 
    ORDER BY dummy_integer ASC LIMIT 20;

次に、問題は、たとえば、いくつかの新しい列車レコードを取得すると、それらを master_table の最後に追加できますが、それらのダミーの整数値はそれらを最後に配置することになります。したがって、ユーザーが私のページを最初から見始めた場合、車/飛行機が前にうまくインターリーブされるのではなく、車の砂漠をページングするまで、新しい列車のデータは表示されません.

上記の(あまり良くない)方法以外にこれを行う良い方法はありますか?

ありがとう

4

2 に答える 2

1

クエリのコンマは実際に結合を実行していませんか?

私はそれを達成するためにUNIONandを使用します:ORDER BY

SELECT id, type, description FROM cars
UNION
SELECT id, type, description FROM planes
UNION
SELECT id, type, description FROM trains
ORDER BY id, type

実施例

LIMITページネーションにはwithを使用できますOFFSET( docsを参照)。

于 2012-06-19T04:37:57.183 に答える
0

オラクルを使用している場合、これはうまくいきます:

select
    1 as typer,
    a.id,
    a.type,
    a.description,
    row_number() over (partition by typer order by typer) as ranker
from
    cars a
union
select
    1 as typer,
    a.id,
    a.type,
    a.description,
    row_number() over (partition by typer order by typer) as ranker
from
    planes a
union
select
    1 as typer,
    a.id,
    a.type,
    a.description,
    row_number() over (partition by typer order by typer) as ranker
from
    trains a
order by
    ranker asc;

列名は変更していませんが、予約語を使用しているため、おそらく最適ではありません。

于 2012-06-19T05:05:53.443 に答える