来自不同来源的分页项目

时间:2018-11-05 17:44:31

标签: php mysql sql pagination mariadb

这是我面临的一个问题:我需要列出一些项目。这些项目来自不同的来源(例如表A,表B,表C),具有不同的属性和性质(尽管有些是常见的)。

如何将它们合并到分页列表中?

我考虑过的选项:

  • 首先获取它们,然后在代码中对其进行排序和分页。这行不通,因为有太多(数千个)项目,而且性能一团糟。

  • 将它们与它们的共享属性一起加入到SQL视图中,完成SQL查询后,仅重新加载分页的项目即可获取其余属性。到目前为止,此方法仍然有效,但是如果源更改/增加,则可能难以维护。

您还有其他选择吗?基本上,最常用/推荐的方式是从两个数据源(SQL或直接在代码中)对项目进行分页。

谢谢。

2 个答案:

答案 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个。