如何使用联合表限制子查询 [MySQL]

Posted

技术标签:

【中文标题】如何使用联合表限制子查询 [MySQL]【英文标题】:How can I limit a subquery [MySQL] with union table 【发布时间】:2021-01-26 03:47:49 【问题描述】:

我有以下表格:

product_category(联合表) product_category_id (PK AI) product_id category_id

类别 category_id (PK AI) 标题 ...等

产品 product_id (PK AI) 标题 命令 等等……

我想通过联合表 (product_category) 获取所有类别及其相关产品,并将其产品限制为每个类别 5 个,基本上是多对多关系,如 netflix 类别轮播(戏剧类别有 5 个相关电影和恐怖类别有 5 部相关的电影等...)我已经尝试过了,但加入没有按预期工作:

SELECT 
*
FROM
product_category AS pc
    INNER JOIN
categories AS cat ON cat.category_id = pc.category_id
    INNER JOIN
(SELECT 
    *
FROM
    products
LIMIT 1 ORDER BY products.order DESC) AS x ON x.product_id = pc.product_id;

所以... ¿如何限制每个类别的产品?我正在使用 mysql 5.7 我不想多次查询数据库以按类别手动获取产品,我想以最干净的方式完成这项工作,最多只查询一两个。 ¿ 有可能吗?

问候。

【问题讨论】:

您能否在当前限制子查询中添加ORDER BY 子句,以便我们知道要保留哪条记录的逻辑是什么? @TimBiegeleisen 我已经在 subQuery 中尝试过“ORDER BY products.product_id”,但它似乎不起作用。还有 GROUP BY。我想按 product_id 保存记录。谢谢。 这不能回答我的问题。 我进行了更改。你能看到最后的编辑吗?请问,你的问题能更“清楚”吗? 【参考方案1】:

在 MySQL 5.7 上,您可以尝试这些方法,使用内部连接来限制具有最新 order 值的产品:

SELECT *
FROM product_category AS pc
INNER JOIN categories AS cat ON cat.category_id = pc.category_id
INNER JOIN products AS p ON p.product_id = pc.product_id
INNER JOIN
(
    SELECT product_id, MAX(`order`) AS latest_order
    FROM products
    GROUP BY product_id
) p2
    ON p2.product_id = p.product_id AND
       p2.latest_order = p.`order`;

与上面别名为p2 的子查询的联接仅限于具有最新order 值的产品记录。旁注:请避免将列命名为 ORDER,这是 MySQL 的保留关键字。

编辑:针对每个订单的前 5 个产品的解决方案,按最近的顺序排列,使用 ROW_NUMBER

WITH cte AS (
    SELECT *, ROW_NUMBER() OVER (PARTITION BY p.product_id ORDER BY `order` DESC) rn
    FROM product_category AS pc
    INNER JOIN categories AS cat ON cat.category_id = pc.category_id
    INNER JOIN products AS p ON p.product_id = pc.product_id
)

SELECT *
FROM cte
WHERE rn <= 5;

【讨论】:

感谢最后的提示,我将不再使用 order 作为列名。例如,如果我限制具有最新订单价值的产品,则可能无法按类别将产品限制为 5。你怎么看?这可以只用一个查询来实现,或者最多可以用两个查询来完成?谢谢,任何帮助或建议将不胜感激。 如果你想要top/bottom 5,那么你真的应该考虑升级到MySQL 8+,这样你就可以使用ROW_NUMBER。我在 5.7 上没有为您解答您的后续问题。 谢谢,您为我指明了正确的方向。我将尝试使用 ROW_NUMBER 并升级我非常旧的 MySQL 引擎版本。如果我可以使用 ROW_NUMBER 进行编辑,我将对其进行编辑。感谢您的帮助,我真的很感激。 @elaineee 对于免费蜜蜂,请查看我的更新答案以获取行号选项。 你摇滚!我真的很感谢您的支持,我不得不进行一些更改以使其适应我的项目,但当然我是根据您的回答做出的。真的很感谢,我过去了一周的工作,为了让它发挥作用,你救了我的命。 现在可以了,。真的很感谢你的帮助,非常感谢。对我有效的代码:WITH cte AS ( SELECT p.*, pc.category_id, ROW_NUMBER() OVER (PARTITION BY pc.category_id ORDER BY pc.category_id) AS row_num FROM product_category AS pc INNER JOIN products AS p ON p.product_id = pc.product_id ) SELECT * FROM cte WHERE row_num &lt;= 3;

以上是关于如何使用联合表限制子查询 [MySQL]的主要内容,如果未能解决你的问题,请参考以下文章

mysql连接查询,子查询,联合查询

MySQL 表关系及多表操作(联合查询连接查询子查询)

MySQL进阶 — 联合查询(外连接内连接子连接合并查询)

MySQL进阶 — 联合查询(外连接内连接子连接合并查询)

MySQL进阶 — 联合查询(外连接内连接子连接合并查询)

mysql数据库的多表查询,子查询,联合查询