简体   繁体   English

高级Mysql查询,如果两个条件匹配不同的子记录行,则获取主记录

[英]Advanced Mysql Query to get master record if two conditions matches on different rows of child records

I was writing a mysql filter query which has a primary table and another table which holds multiple records against each record of primary table (I will call this table child). 我正在编写一个mysql过滤器查询,它有一个主表和另一个表,它对每个主表记录保存多个记录(我将这个表称为子表)。

Am trying to write a query which fetches record of primary table based on its values on child table. 我试图编写一个查询,根据子表上的值来获取主表的记录。 If the child table condition is one then I will be able to do it simply by joining, but I have 2 conditions which falls on same field. 如果子表条件为1,那么我只需加入即可完成,但我有2个条件属于同一个字段。

For ex.
table 1:
id   name  url
1    XXX   http://www.yahoo.com
2    YYY   http://www.google.com
3    ZZZ   http://www.bing.com

table 2:
id masterid optionvalue
1  1        2
2  1        7
3  2        7
4  2        2
5  3        2
6  3        6

My query has to return unique master records when the optionvalue matches only both 2 different conditions match on second table. optionvalue只匹配第二个表上的两个不同条件匹配时,我的查询必须返回唯一主记录。 I wrote query with IN... 我用IN写了查询...

select * from table1 
left join table2 on table1.id=table2.masterid 
where table2.optionvalue IN(2,7) group by table1.id;

This gets me all 3 records because IN is basically checking 'OR', but in my case I should not get 3rd master record because it has values 2,6 (there is no 7). 这得到了我所有的3条记录,因为IN基本上是在检查'OR',但在我的情况下,我不应该获得第3主记录,因为它的值为2,6(没有7)。 If I write query with 'AND' then am not getting any records... 如果我用'AND'写查询,那么我没有得到任何记录......

select * from table1 
left join table2 on table1.id=table2.masterid 
where table2.optionvalue = 2 and table2.optionvalue = 7;

This will not return records as the and will fail as am checking different values on same column. 这不会返回记录,因为我会检查同一列上的不同值。 I wanted to write a query which fetches master records which has child records with field optionvalues holds both 2 and 7 on different records. 我想写这取其中有子记录与现场主记录的查询optionvalues上不同的记录同时拥有2和7。

Any help would be much appreciated. 任何帮助将非常感激。

Indeed, as AsConfused hinted, you need to two joins to TABLE2 using aliases 实际上,正如AsConfused暗示的那样,你需要使用别名将两个连接到TABLE2

-- both of these are tested : - both of these are tested

-- find t1 where it has 2 and 7 in t2

    select t1.*
    from table1 t1
    join table2 ov2 on t1.id=ov2.masterid and ov2.optionValue=2
    join table2 ov7 on t1.id=ov7.masterid and ov7.optionValue=7

-- find t1 where it has 2 and 7 in t2, and no others in t2

select t1.*, ovx.id
    from table1 t1
      join table2 ov2 on t1.id=ov2.masterid and ov2.optionValue=2
      join table2 ov7 on t1.id=ov7.masterid and ov7.optionValue=7
      LEFT OUTER JOIN table2 ovx on t1.id=ovx.masterid and ovx.optionValue not in (2,7)
    WHERE ovx.id is null

You can try something like this (no performance guarantees, and assumes you only want exact matches): 您可以尝试这样的事情(没有性能保证,并假设您只想要完全匹配):

select table1.* from table1 join
(select masterid, group_concat(optionvalue order by optionvalue) as opt from table2 
group by masterid) table2_group on table1.id=table2_group.masterid
where table2_group.opt='2,7';

http://sqlfiddle.com/#!9/673094/9 http://sqlfiddle.com/#!9/673094/9

select * from t1 where id in (select masterid from t2 where (t2.masterid in (select masterid from t2 where optionvalue=2)) and (t2.masterid in (select masterid from t2 where optionvalue=7))) select * from t1 where id in(select tid from t2 where(t2.masterid in(select selectid from t2 where optionvalue = 2))和(t2.masterid in(select selectid from t2 where optionvalue = 7)))

Old school :-) Query took 0.0009 sec. 老学校:-)查询耗时0.0009秒。

This can also be done without the joins using correlated exists subqueries. 这也可以在没有使用相关的存在子查询的连接的情况下完成。 That may be more efficient. 这可能更有效率。

select *
  from table1 
 WHERE EXISTS (SELECT 1 FROM table2 WHERE table1.id=table2.masterid and optionvalue = 2)
   AND EXISTS (SELECT 1 FROM table2 WHERE table1.id=table2.masterid and optionvalue = 7)

If this is to be an exclusive match as suggested by, "when the optionvalue matches only both 2 different conditions match on second table" then you could ad yet a third exists condition. 如果这是一个独家匹配,建议如下,“当选项值只匹配两个不同的条件匹配第二个表”时,你可能还有第三个存在条件。 Performance-wise this may start to break down. 性能方面,这可能会开始瓦解。

AND NOT EXISTS (SELECT 1 FROM table2 WHERE table1.id=table2.masterid AND optionvalue  NOT IN (2,7)

Edit: A note on correlated subqueries from Which one is faster: correlated subqueries or join? 编辑:关于相关子查询的注释, 其中一个更快:相关子查询或连接? .

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM