我有三个数据表:
table: cars [10,000 rows]
table: planes [2,000 rows]
table: trains [50 rows]
我希望能够向用户显示从三个表中获取的数据页面,如:
car
plane
train
car
plane
train
...
关键是他们可以继续分页,查看每种类型之一,直到每个表都用完为止。例如,在某些时候,每个页面只包含汽车,因为飞机和火车表将在汽车表之前耗尽。
我是否可以运行查询以从每个表中获取一行,直到达到限制为止?类似的东西:
SELECT * FROM cars, planes, trains ORDER BY (natural row ordering?) LIMIT 20;
我能想到的唯一方法是创建一个主表,并在插入它们时为每一行分配一个虚拟整数:
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的末尾,但是它们的虚拟整数值会将它们一直放在最后。因此,如果用户从一开始就开始查看我的页面,他们将不会看到更新的列车数据,直到他们翻阅汽车沙漠,而不是与汽车/飞机向前交叉。
除了上述(不那么好)之外,还有什么好办法吗?
由于
答案 0 :(得分:1)
查询中的逗号实际上是否实际执行了连接?
我使用UNION
和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
与OFFSET
一起使用(请参阅docs)。
答案 1 :(得分:0)
如果你使用的是oracle,这对你有用:
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;
我没有更改你的列名,但你使用的是一些保留字,可能不是最好的。