如何使用联合表限制子查询 [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 <= 3;
以上是关于如何使用联合表限制子查询 [MySQL]的主要内容,如果未能解决你的问题,请参考以下文章