MySQL查询根据特定标记组合在提取行时返回不需要的行

时间:2016-01-19 19:31:44

标签: php mysql sql

我在Windows 8 PC中运行PHP + MySQL。我有一张表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   ║
╚═════════╩══════╩═════╝

我有输入101102。我希望输出像;

2,5
6,8

查询将查找组合101,102,并返回完全相同的组合不同的批号。除此之外,我想避免重复的行。此处11115555具有相同的标签,其相应的批号为tag s(具有相同批次的完全相同的组合),因此我只需要一行而不是两行。即使8888标记101102标记不同lot,也不能考虑列表,因为它还包含标记103。简而言之,我希望产品具有精确的101, 102组合,我不希望产品带有任何额外的标签,而且我不想要任何缺少标签的东西。

我有一个如下的查询;

SELECT DISTINCT GROUP_CONCAT(m.lot) FROM mytable m
WHERE m.tag IN (101,102) 
AND (SELECT COUNT(m.product) FROM mytable m2 WHERE m.product = m2.product)>1
GROUP BY m.product;

返回;

2,5
2
5,2
1,3
6,8

我该如何解决这个问题?有没有更好的方法来完成我想要的东西?

这是从http://sqlfiddle.com/#!9/d11d6

开始的小提琴

3 个答案:

答案 0 :(得分:2)

我建议使用简单连接:

SELECT DISTINCT a.lot, b.lot
FROM mytable a
    INNER JOIN mytable b ON b.product = a.product AND NOT EXISTS (SELECT * FROM product WHERE tag NOT IN (a.tag, b.tag))
WHERE a.tag = 101 and b.tag = 102

答案 1 :(得分:1)

我想知道这是否符合您的要求:

select group_concat(lot order by lot)
from mytable
group by product
having group_concat(tag order by tag) = '101,102';

这似乎会返回您想要的结果。使用where子句会更有效:

select group_concat(lot order by lot)
from mytable
where tag in ('101', '102')
group by product
having group_concat(tag order by tag) = '101,102';

答案 2 :(得分:0)

通过按产品分组,HAVING子句明确地只查找那些同时具有101和102以及NO OTHER的产品。每个产品合格后,都会包含连续批次。如果另一个具有相同的连接,则只返回一个集合。由于您在产品中使用相同标签101的重复条目,我只关心是否找到一个IS而不管它是否重复,因此MAX()分别为101和102两者= 1。

message

如果您想查看每个产品的比较方式,请删除HAVING子句以查看其各自的值

self

我为你创建了一个SQLFiddle个实例。几件小事。我将列名更改为“tag1”,“lot1”。

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;

所以我的查询针对你的SQLFiddle运行并且有结果

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