mysql - MySQL:对添加的 JOIN 表使用 LIMIT
问题描述
看法
该应用程序的视图包含一个显示一堆轮播的页面(每个轮播 =一个标签),每个都应包含 5 个产品:
+-------------------------------------+
|Page |
|+-----------------------------------+|
||Tag1 ||
||+--------+ +--------+ +--------+||
|||Product1| |Product2| .. |Product5|||
||+--------+ +--------+ +--------+||
|+-----------------------------------+|
|... |
|+-----------------------------------+|
||TagN ||
||... ||
+-------------------------------------+
数据库
页面
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(16) | NO | UNI | NULL | |
+-------+-------------+------+-----+---------+----------------+
CREATE TABLE `pages` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(16) COLLATE utf8mb4_unicode_ci NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
pages_tags
+--------------+------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| page_id | int(11) | NO | MUL | NULL | |
| tag_id | int(11) | NO | MUL | NULL | |
| position | tinyint(4) | NO | | NULL | |
+--------------+------------+------+-----+---------+----------------+
CREATE TABLE `pages_tags` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`page_id` int(11) NOT NULL,
`tag_id` int(11) NOT NULL,
`position` tinyint(4) NOT NULL,
PRIMARY KEY (`id`),
KEY `page_id` (`page_id`),
KEY `tag_id` (`tag_id`),
CONSTRAINT `pages_tags_ibfk_1` FOREIGN KEY (`page_id`) REFERENCES `pages` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `pages_tags_ibfk_2` FOREIGN KEY (`tag_id`) REFERENCES `tags` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=663 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
标签
+---------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(128) | NO | | NULL | |
+---------+--------------+------+-----+---------+----------------+
CREATE TABLE `tags` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(128) COLLATE utf8mb4_unicode_ci NOT NULL,
PRIMARY KEY (`id`),
) ENGINE=InnoDB AUTO_INCREMENT=149 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
产品标签
+------------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+---------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| product_id | int(11) | NO | MUL | NULL | |
| tag_id | int(11) | NO | MUL | NULL | |
+------------+---------+------+-----+---------+----------------+
CREATE TABLE `products_tags` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`product_id` int(11) NOT NULL,
`tag_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `tag_id` (`tag_id`),
KEY `bouquet_id` (`product_id`),
CONSTRAINT `products_tags_ibfk_1` FOREIGN KEY (`product_id`) REFERENCES `products` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `products_tags_ibfk_2` FOREIGN KEY (`tag_id`) REFERENCES `tags` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=5698 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
产品
+-------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(128) | NO | UNI | NULL | |
+-------------+--------------+------+-----+---------+----------------+
CREATE TABLE `products` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(128) COLLATE utf8mb4_unicode_ci NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=335 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
目标
目标是获得一个包含页面上所有标签的输出,每个标签最多包含 5 个产品。
询问
这是我在卡住之前得到的查询:
SELECT t.name, p.name
FROM pages a
LEFT JOIN pages_tags a_t ON a_t.page_id = a.id
LEFT JOIN tags t ON t.id = a_t.tag_id
LEFT JOIN products p ON p.id = (
SELECT p_t.product_id FROM products_tags p_t WHERE p_t.tag_id = t.id LIMIT 1
);`
问题
- 无法使用
limit 5
:
ERROR 1242 (21000):子查询返回多于 1 行
- 无法使用
in
+limit
:
错误 1235 (42000): 这个版本的 MySQL 还不支持 'LIMIT & IN/ALL/ANY/SOME 子查询'
需要帮助。
我要返回的内容(示例)
- 页
- 标签1
- 产品1
- 产品2
- 产品3
- 产品4
- 产品5
- 标签2
- 产品6
- 产品7
- 产品8
- 产品9
- 产品10
- ...
- 标签N
- 产品K
- productL(但总是最大值为 5)
- 标签1
解决方案
您可以使用标量子查询来做您想做的事情:
p.id <= (SELECT p_t.product_id
FROM products_tags p_t
WHERE p_t.tag_id = t.id
ORDER BY p_t.product_id
LIMIT 1 OFFSET 4
)
但是,如果少于 5 行,这将不起作用。在这种情况下,您可以使用coalesce()
:
p.id <= COALESCE( (SELECT p_t.product_id
FROM products_tags p_t
WHERE p_t.tag_id = t.id
ORDER BY p_t.product_id
LIMIT 1 OFFSET 4
), p.id
)
注意:这假设您希望按顺序排列产品 ID。
推荐阅读
- sql - 将 SQL 模型复制到 Ruby on Rails postgresql 模型中
- mule - 在tomcat 7服务器中的mule应用程序中处理请求时出错
- c# - .Net CAD2010:加载cuix文件时出错
- google-cloud-platform - 谷歌云存储SDK的正确使用方法
- javascript - 如何模拟在测试模块中导入的变量,它不是函数参数(使用 describe.each 执行此操作,并在每个测试更改模拟值)
- python - 使用 Python 在 Rasa 中找不到模型“en”
- kubernetes - 无法在 kubernetes-1.11.3 内的 ignite(v 2.7) 节点之间形成连接
- oracle-adf - 只打印页面中的记录而不是表中的所有记录
- json - Kotlin 没有将“is”作为 json 键的开始
- .net - 阅读来自 Exchange 服务器的电子邮件最佳解决方案