【问题标题】:MySQL/MariaDB - LIMIT joined query result while not losing any primary IDMySQL/MariaDB - 在不丢失任何主 ID 的情况下限制连接查询结果
【发布时间】:2016-06-27 11:04:07
【问题描述】:

我知道如何使用LIMIT a,b 限制查询结果,但是如果我想使用JOINs 创建的LIMIT 查询具有一个主ID 的多行,同时每个ID 至少保留一行,该怎么办?

让我解释一下……*
我有一个帖子表,然后是一个类别表。
但是,一篇文章可以属于更多类别。
当我查询帖子时,我还想同时查询它们的类别...
...问题是我最多只需要 1 个类别。每 1 个帖子结果(我不在乎哪一个)

当前(示例)结果

ID   | title       | content | category_ID | category_name
1    | First Post  | ....... |   2         | Boring Articles
1    | First Post  | ....... |   5         | Interesting Articles
1    | First Post  | ....... |   1         | Mojo Tips
2    | Second Post | ....... |   5         | Interesting Articles
3    | Third Post  | ....... |   5         | Interesting Articles
3    | Third Post  | ....... |   4         | Fitness
4    | Fourth Post | ....... |   NULL      | NULL

所需的(示例)结果 - 请注意,每个帖子 ID 至少保留一行!

ID   | title       | content | category_ID | category_name
1    | First Post  | ....... |   2         | Boring Articles
2    | Second Post | ....... |   5         | Interesting Articles
3    | Third Post  | ....... |   5         | Interesting Articles
4    | Fourth Post | ....... |   NULL      | NULL

但如果我只是做一些事情

SELECT * FROM posts
LEFT JOIN relationships USING(ID)
LEFT JOIN categories USING(category_ID)
LIMIT 0,4

这会发生(丢失所需的数据 - 不再是每 1 个 ID 1 行...):

ID   | title       | content | category_ID | category_name
1    | First Post  | ....... |   2         | Boring Articles
1    | First Post  | ....... |   5         | Interesting Articles
1    | First Post  | ....... |   1         | Mojo Tips
2    | Second Post | ....... |   5         | Interesting Articles

PS:我想知道如何在 MySQL/MariaDB 中解决这个问题,如果在使用一个或另一个时这样做有什么不同 - 那么有什么区别呢? :)

【问题讨论】:

  • 如果您愿意,请考虑遵循以下简单的两步操作: 1. 如果您还没有这样做,请提供适当的 CREATE 和 INSERT 语句(和/或 sqlfiddle),以便我们可以更容易复制问题。 2. 如果您尚未这样做,请提供与步骤 1 中提供的信息相对应的所需结果集。
  • 什么不清楚?我无法想象当我的问题是关于限制现有结果时你为什么需要创建/插入语句......而且我确实提供了一个示例 SQL 查询和结果......最重要的是,我的问题更多的是一般问题而不是特定于数据库的...
  • 没有数据集的结果集就像没有棒棒糖的棍子。一点都不好玩。不“关心哪一个”有时表明设计不佳。
  • @Strawberry 我不同意,当你有一根棍子时,你仍然知道它是一根棍子,但现在仍然如何将它分成两半:) 我同意“不携带哪个”可能表明设计不佳,但在这种特殊情况是相反的(在特定的最终用法中:))

标签: mysql join distinct limit mariadb


【解决方案1】:

一种方法使用子查询:

SELECT p.*,
       (SELECT c.category_name
        FROM relationships r JOIN
             categories c
             USING (category_ID)
       WHERE r.id = p.id
       LIMIT 1
      ) as category_name
FROM posts p
LIMIT 0, 4;

注意:在使用LIMIT 时,您通常会有一个ORDER BY

另一种方法使用GROUP BY

SELECT p.*, c.*
FROM posts p LEFT JOIN
     relationships r
     USING (ID) LEFT JOIN
     categories c
     USING (category_ID)
GROUP BY p.id
LIMIT 0, 4;

我不喜欢这样使用GROUP BY,但它是一个有效的 MySQL 扩展。

【讨论】:

  • 嗯,您以一种非常特殊的方式使用“有效”一词。
  • @Gordon Linoff - 另一个问题 - 你知道哪个更快(考虑到大数据,否则我会自己测试:))
  • @jave.web 。 . .第一个应该更快。第二个中的group by 会使事情变慢很多。当然,您可以对此进行测试,但这是我的期望。
  • @GordonLinoff 为什么会按组减慢速度? :)(与后者相比)
  • @jave.web 。 . . MySQL 对group by 使用排序,并且增长为 O(n log n)。这意味着数据变得越来越大,排序需要的时间越来越长。相比之下,第一种方法应该简单地通过在几个索引中查找一个值来找到匹配的类别。因此,第一个查询应该比group by 更快。
猜你喜欢
  • 1970-01-01
  • 2011-01-17
  • 1970-01-01
  • 1970-01-01
  • 2021-08-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-07
相关资源
最近更新 更多