这是我面临的一个问题:我需要列出一些项目。这些项目来自不同的来源(例如表A,表B,表C),具有不同的属性和性质(尽管有些是常见的)。
如何将它们合并到分页列表中?
我考虑过的选项:
首先获取它们,然后在代码中对其进行排序和分页。这行不通,因为有太多(数千个)项目,而且性能一团糟。
将它们与它们的共享属性一起加入到SQL视图中,完成SQL查询后,仅重新加载分页的项目即可获取其余属性。到目前为止,此方法仍然有效,但是如果源更改/增加,则可能难以维护。
您还有其他选择吗?基本上,最常用/推荐的方式是从两个数据源(SQL或直接在代码中)对项目进行分页。
谢谢。
答案 0 :(得分:1)
实际上,我最近不得不回答类似的情况,特别是在两个大表之间进行报告并在两个表之间进行分页。我的答案是使用子查询,如下所示:
SELECT
t1.id as 't1_id',
t1.name as 't1_name',
t1.attribute as 't1_attribute',
t2.id as 't2_id',
t2.name as 't2_name',
t2.attribute as 't2_attribute',
l.attribute as 'l_attribute'
FROM (
SELECT
id, name, attribute
FROM
table1
/* You can perform joins in here if you want, just make sure you're using your aliases right */
/* You can also put where statements here */
ORDER BY
name DESC, id ASC
LIMIT 0,50
) as t1
INNER JOIN (
SELECT
id,
name,
attribute
FROM
table2
ORDER BY
attribute ASC
LIMIT 250,50
) as t2
ON t2.id IS NOT NULL
LEFT JOIN
linkingTable as l
ON l.t1Id = t1.id
AND l.t2Id = t2.id
/* Do your wheres and stuff here */
/* You shouldn't need to do any additional ordering or limiting */
答案 1 :(得分:1)
如果UNION
解决了该问题,那么这里有一些语法和优化技巧。
这将提供10行页面的第21页:
(
( SELECT ... LIMIT 210 )
UNION [ALL|DISTINCT]
( SELECT ... LIMIT 210 )
) ORDER BY ... LIMIT 10 OFFSET 200
请注意,210 = 200 + 10。您无法信任内部OFFSET
中的SELECTs
。
使用UNION ALL
来提高速度,但是如果SELECTs
之间可能存在重复的行,则明确地说出UNION DISTINCT
。
如果您删除了太多的括号,则会得到语法错误或“错误”结果。
如果最后得到一个子查询,请重复ORDER BY
而不是LIMIT
:
SELECT ...
FROM (
( SELECT ... LIMIT 210 )
UNION [ALL|DISTINCT]
( SELECT ... LIMIT 210 )
ORDER BY ... LIMIT 10 OFFSET 200
) AS u
JOIN something_else ON ...
ORDER BY ...
可能包含JOIN
的一个原因是为了提高性能-子查询u
将结果集精简到只有10行,因此JOIN
仅需要查找10件事起来将JOIN
放入其中将导致大量加入,然后减少到只有10个。