[英]Mysql select query group concat
我有一个选择查询来构建,我无法让它工作正常。 我希望从更高级的MySQL开发人员那里获得一些消息。 所以我的表是:
CREATE TABLE IF NOT EXISTS `gv` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`option_id` int(11) NOT NULL,
`group_id` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=7 ;
INSERT INTO `gv` (`id`, `option_id`, `group_id`) VALUES
(1, 1, 1),
(2, 2, 2),
(3, 3, 2),
(4, 4, 3),
(5, 5, 4),
(6, 6, 4);
CREATE TABLE IF NOT EXISTS `igv` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`item_id` int(11) NOT NULL,
`gv_id` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=9 ;
INSERT INTO `igv` (`id`, `item_id`, `gv_id`) VALUES
(1, 1, 1),
(2, 1, 3),
(3, 2, 1),
(4, 2, 2),
(6, 3, 5),
(7, 4, 2),
(8, 2, 6);
CREATE TABLE IF NOT EXISTS `items` (
`item_id` int(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`item_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=6 ;
INSERT INTO `items` (`item_id`) VALUES
(1),
(2),
(3),
(4),
(5);
现在我将解释这些表正在做什么:
gv来自group_values。 组就像项目的属性。 例如:颜色。
igv来自项目组值。 项目是我项目中的主要实体,就像产品一样。
项目来自项目:)我已将此示例简化为仅一列,item_id。
我需要查询的内容:
好吧,在我的应用程序中,我有一个选定的项目(my_item)(附加了0或更多组值)。 我需要定义完全相同group_values的所有项目,或者没有为my_item组指定的值。 在php中,我可以将所有附加的组提取为带有id的数组,也包括所有group_values。 但我发现无法从这个数据库中选择我需要的东西。 我将非常感谢为这个庞大的时间消费选择提供的任何输入。
谢谢!
一个简短的草图示例。 在左侧,我们有匹配所有正确项目的项目(用逗号分隔)。
好的,首先我们需要找到一个与另一个项目匹配的组的所有项目:
SELECT igv.item_id, sigv.item_id FROM igv
INNER JOIN gv ON igv.gv_id = gv.id
INNER JOIN gv sgv ON gv.group_id = sgv.group_id
INNER JOIN igv sigv ON sigv.gv_id = sgv.id
WHERE igv.item_id = items.item_id
AND sigv.item_id = similar.item_id
那么我们是时候可以选择不匹配只关心:
SELECT igv.item_id, sigv.item_id dissimilar FROM igv
INNER JOIN gv ON igv.gv_id = gv.id
INNER JOIN gv sgv ON gv.group_id = sgv.group_id
INNER JOIN igv sigv ON sigv.gv_id = sgv.id
WHERE igv.item_id = items.item_id
AND sigv.item_id = similar.item_id
AND gv.option_id != sgv.option_id
然后我们只对以上未选择的项目感兴趣。 这可以使用NOT EXISTS
或LEFT JOIN
来完成。 以下是使用NOT EXISTS
执行此操作的方法:
SELECT items.item_id, similar.item_id similar_id
FROM items similar
INNER JOIN items
WHERE items.item_id != similar.item_id
AND NOT EXISTS (
SELECT igv.item_id, sigv.item_id dissimilar FROM igv
INNER JOIN gv ON igv.gv_id = gv.id
INNER JOIN gv sgv ON gv.group_id = sgv.group_id
INNER JOIN igv sigv ON sigv.gv_id = sgv.id
WHERE sigv.item_id = similar.item_id
AND igv.item_id = items.item_id
AND gv.option_id != sgv.option_id
)
结果:
ITEM_ID SIMILAR_ID
1 3
1 5
2 4
2 5
3 1
3 4
3 5
4 2
4 3
4 5
5 1
5 2
5 3
5 4
更新:
根据评论中的逻辑, 如果我理解正确 ,并且您的测试数据,下表显示了您为查询提供哪个item_id所需的结果。
id_provided | result
--------------------
1 2 & 5
2 1 & 4 & 5
3 5
4 2 & 5
5 -
如果这是正确的,以下查询将给出所需的结果:
SELECT
COALESCE(i2.item_id, i.item_id)
FROM
items i
LEFT JOIN igv ON igv.item_id = i.item_id
LEFT JOIN gv ON igv.gv_id = gv.id
LEFT JOIN gv gv2 ON gv.group_id = gv2.group_id AND gv.option_id = gv2.option_id
LEFT JOIN igv igv2 ON gv2.id = igv2.gv_id
LEFT JOIN items i2 ON igv2.item_id = i2.item_id
WHERE i.item_id = $yourItemId
AND i2.item_id != i.item_id OR i2.item_id IS NULL
我不确定我是否理解你想要的东西,我不确定以下查询是否能得到你想要的东西,因为你没有说出预期的输出是什么,你的测试数据是不够的。 无论如何,这是我的镜头:
SELECT DISTINCT i.item_id FROM items i LEFT JOIN igv ON igv.item_id = i.item_id LEFT JOIN gv ON igv.gv_id = gv.id GROUP BY i.item_id HAVING GROUP_CONCAT(CONCAT(COALESCE(gv.option_id, 0), COALESCE(gv.group_id, 0)) ORDER BY gv.option_id, gv.group_id SEPARATOR ':') = ( SELECT GROUP_CONCAT(CONCAT(COALESCE(sq_gv.option_id, 0), COALESCE(sq_gv.group_id, 0)) ORDER BY sq_gv.option_id, sq_gv.group_id SEPARATOR ':') FROM items sq_i LEFT JOIN igv sq_igv ON sq_igv.item_id = sq_i.item_id LEFT JOIN gv sq_gv ON sq_igv.gv_id = sq_gv.id WHERE sq_i.item_id = $yourItemId /*insert the item_id here*/ GROUP BY sq_i.item_id )
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.