我有那些MySQL(简化)模式:
CREATE TABLE `library` (
`id` varchar(32) NOT NULL,
`app` varchar(32) NOT NULL,
`filename` varchar(255) NOT NULL,
PRIMARY KEY (`id`),
KEY `app` (`app`,`filename`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `tags` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`app` varchar(32) DEFAULT NULL,
`tag` varchar(55) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `app` (`app`)
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8;
CREATE TABLE `library_tags` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`file` varchar(32) DEFAULT NULL,
`tag` int(10) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=101 DEFAULT CHARSET=utf8;
我的目标是为每个“标签”获取每个“库”条目。如果没有标签与库条目相关联,则它会在标签的字段中返回NULL。
这样做可以做到:
SELECT SQL_CALC_FOUND_ROWS library.*,
GROUP_CONCAT( tags.`id` ORDER BY tags.`id` ASC SEPARATOR ',' ) as `tag_id`,
GROUP_CONCAT( tags.`tag` ORDER BY tags.`id` ASC SEPARATOR ',' ) as `tag_name`
FROM `library` AS library
LEFT JOIN `library_tags` AS libtags
ON library.`id` = libtags.`file`
LEFT JOIN `tags` AS tags
ON libtags.`tag` = tags.`id`
WHERE library.`app` = "53bd8997ad2ee"
GROUP BY library.`id`
ORDER BY library.`created` DESC
LIMIT 99999 OFFSET 0
我的下一步是添加一个限制,根据标签的id返回库的条目,如下所示:
SELECT SQL_CALC_FOUND_ROWS library.*,
GROUP_CONCAT( tags.`id` ORDER BY tags.`id` ASC SEPARATOR ',' ) as `tag_id`,
GROUP_CONCAT( tags.`tag` ORDER BY tags.`id` ASC SEPARATOR ',' ) as `tag_name`
FROM `library` AS library
LEFT JOIN `library_tags` AS libtags
ON library.`id` = libtags.`file`
LEFT JOIN `tags` AS tags
ON libtags.`tag` = tags.`id`
WHERE library.`app` = "53bd8997ad2ee"
AND tags.`id` IN (9,14)
GROUP BY library.`id`
ORDER BY library.`created` DESC
LIMIT 99999 OFFSET 0
也可以,但GROUP_CONCAT受限制影响,每个条目只返回选定的标签,而不是每个条目的完整标签列表。
我的问题是“如何使用每个条目的完整标记列表保留此单个查询?”
其他问题是:“这会影响MySQL的性能吗?”
感谢您的帮助
答案 0 :(得分:0)
将库标签限制放在LEFT JOIN条件中..
SELECT SQL_CALC_FOUND_ROWS library.*,
GROUP_CONCAT( tags.`id` ORDER BY tags.`id` ASC SEPARATOR ',' ) as `tag_id`,
GROUP_CONCAT( tags.`tag` ORDER BY tags.`id` ASC SEPARATOR ',' ) as `tag_name`
FROM `library` AS library
LEFT JOIN `library_tags` AS libtags
ON library.`id` = libtags.`file`
LEFT JOIN `tags` AS tags
ON libtags.`tag` = tags.`id`
AND tags.`id` IN (9,14)
WHERE library.`app` = "53bd8997ad2ee"
GROUP BY library.`id`
ORDER BY library.`created` DESC
LIMIT 99999 OFFSET 0
这会过滤附加的标签,而不是LEFT JOIN完成后返回的行。它应该以与第一次查询相同的速度运行,如果不是更快的话。