When performing the product group, the HAVING clause is clearly looking for ONLY those products that have both 101 and 102 and NO OTHER. Once each product is qualified, it includes concatenated batches. If the other has the same concatenation, only one set is returned. Because of your duplicate entries of the same tag 101 inside the product, I can only do if one of them is found regardless of its duplication, therefore, MAX () for 101 and 102 are both = 1, respectively.
select DISTINCT group_concat( DISTINCT m.lot ORDER BY m.lot ASC SEPARATOR ',' ) from myTable m group by m.product having MAX( case when m.tag = '101' then 1 else 0 end ) = 1 AND MAX( case when m.tag = '102' then 1 else 0 end ) = 1 AND sum( case when m.tag in ( '101', '102' ) then 0 else 1 end ) = 0;
And if you want to see how each individual product is compared, delete the HAVING clause to see their respective values.
select m.product, group_concat( DISTINCT m.lot ORDER BY m.lot ASC SEPARATOR ',' ), sum( case when m.tag in ( '101', '102' ) then 1 else 0 end ) as WantTags, sum( case when m.tag in ( '101', '102' ) then 0 else 1 end ) as OtherTags from myTable m group by m.product
I created an SQLFiddle instance for you. A few minor things. I changed the column names to "tag1", "lot1".
select DISTINCT group_concat( DISTINCT m.lot1 ORDER BY m.lot1 ASC SEPARATOR ',' ) from myTableXYZ m group by m.product having MAX( case when m.tag1 = 101 then 1 else 0 end ) = 1 AND MAX( case when m.tag1 = 102 then 1 else 0 end ) = 1 AND sum( case when m.tag1 in ( 101, 102 ) then 0 else 1 end ) = 0;
So my query runs against your SQLFiddle and has the results
2,5 1,3,5 6,8
DRapp source share