我有一个表格mytable
如下所示;
╔═════════╦══════╦═════╗
║ product ║ tag ║ lot ║
╠═════════╬══════╬═════╣
║ 1111 ║ 101 ║ 2 ║
║ 1111 ║ 102 ║ 5 ║
║ 2222 ║ 103 ║ 6 ║
║ 3333 ║ 104 ║ 2 ║
║ 4444 ║ 101 ║ 2 ║
║ 5555 ║ 101 ║ 2 ║
║ 5555 ║ 102 ║ 5 ║
║ 6666 ║ 102 ║ 2 ║
║ 6666 ║ 103 ║ 5 ║
║ 7777 ║ 101 ║ 2 ║
║ 7777 ║ 102 ║ 5 ║
║ 7777 ║ 103 ║ 6 ║
║ 8888 ║ 101 ║ 1 ║
║ 8888 ║ 102 ║ 3 ║
║ 8888 ║ 103 ║ 5 ║
║ 9999 ║ 101 ║ 6 ║
║ 9999 ║ 102 ║ 8 ║
╚═════════╩══════╩═════╝
我有一个这样的查询;
select distinct group_concat(lot order by lot)
from `mytable`
group by product
having group_concat(tag order by tag) = '101,102';
这应该给我一个输出,比如;
2,5
6,8
查询将查找101,102
的组合,并返回具有不同批号的完全相同的组合。除此之外,我想避免重复的行。在这里,1111
和 5555
具有相同的标签,具有与 tag
s 相同的相应批号(具有相同批次的完全相同的组合),所以我只想要一行而不是 2 行。即使8888
具有不同lot
的标签101
和102
,也不能考虑将其列入列表,因为它还包括标签103
。简而言之,我想要具有精确101, 102
组合的产品,我不想要带有任何额外标签的产品,也不想要任何缺少标签的产品。
代码工作正常。但是有一个问题。如果我101,102
输入,查询工作正常。但是如果我给出102,101
作为输入,那么我没有得到任何行,但我想得到与上一个条件一样的确切结果,忽略给出标签号的顺序。此外,有时可以有两个以上的数字作为输入,如101,102,103
、101,102,103,104
等。
我该怎么做?这是一个小提琴 http://sqlfiddle.com/#!9/7a78bb/11/0
如果你也喜欢一个PHP解决方案....一个可能的解决方案是通过 PHP 对组合进行排序,并在字符串中的值序列中格式化值。
$tmp = explode(',', '101,102,103,104');
sort($tmp);
$myComb = implode(',',$tmp);
$sql="select distinct group_concat(lot order by lot)
from `mytable`
having group_concat(tag order by tag) = " . myComb . " ; ";
虽然我倾向于使用 php 和 mysql 的组合,但我想我会玩一玩,看看我是否可以想出一个纯 SQL 版本:
SELECT DISTINCT GROUP_CONCAT(lot ORDER BY lot)
FROM `mytable`
GROUP BY product
HAVING COUNT(DISTINCT IF(FIND_IN_SET(tag, '101,102'), tag, NULL)) = 1 + LENGTH('101,102') - LENGTH(REPLACE('101,102', ',', ''))
AND COUNT(tag) = 1 + LENGTH('101,102') - LENGTH(REPLACE('101,102', ',', ''));
这将不关心逗号分隔的值列表的顺序。但效率不高!