Mysql NOT IN子句查询不会返回我想要的内容

时间:2018-03-02 12:31:50

标签: mysql sql notin

我认为我不明白,但我有一个非常奇怪的结果而不是。

我有这种表

TABLE membres

idMembre
1
2
...

表membres_has_domaines

idMembre  idDomaine
1         10
1         11
1         40
2         10
2         13
2         20
3         40
3         22

我运行此查询

select m.idMembre from membres m 
inner join membres_has_domaines md on m.idMembre=md.idMembre 
where md.idDomaine not in (40) 
group by m.idMembre 

结果让我回头

idMembre
1
2
3

问题是......为什么用户1和3在这个结果中?

非常感谢你的帮助

编辑: 在第一次回答后,我理解了这个问题...... 实际上我的要求要复杂得多。我正在处理由HTML表单生成的完整动态过滤系统,您可以在其中选择参数... 请求看起来像那样。在这里,我希望成员具有域匹配(1,2),不包括具有域27的成员并且具有(64,4,24)中的国家

select m.idMembre,  memberName, 
GROUP_CONCAT(distinct d.domaineName SEPARATOR ", ") as domaines , 
GROUP_CONCAT(distinct a.zipAdresse SEPARATOR ", ") as zips, 
GROUP_CONCAT(distinct p.countryName SEPARATOR ", ") as countryNames 
from membres
 m left join titres t on m.idTitre=t.idTitre 
left join civilites c on m.idCivilite=c.idCivilite 
left join adresses a on a.idMembre=m.idMembre left 
join pays p on a.idCountry =p.idCountry 
left join emails e on e.idMembre=m.idMembre 
left join membres_has_domaines md on md.idMembre=m.idMembre 
left join domaines d on md.idDomaine=d.idDomaine 
where 1=1 and md.idDomaine in (1, 2) 
and md.idDomaine not like '27' 
and a.idCountry in (64, 4, 24) 
group by m.idMembre

注意......这个查询不能完成这项工作......原因与我最初的简化示例相同。

我不知道如果不使用子条款或子查询我是否可以做到这一点......它非常复杂。我认为,子查询是唯一的方法吗?你怎么看 ? ...

3 个答案:

答案 0 :(得分:2)

正如其他人所说,每个成员都有很多记录,当至少有一个记录符合您的not in条件时,它会出现在结果集中。

一种方法是查找具有违规记录的所有成员,然后返回补充集:

SELECT 
    m.idMembre 
FROM 
    membres_has_domaines m
WHERE
    m.idMembre NOT IN (
        SELECT idMembre 
        FROM membres_has_domaines 
        WHERE idDomaine = 40
    );

答案 1 :(得分:1)

它们在结果中,因为您的数据包含与not in条件匹配的行。

如果您希望用户完全没有“40”,那么您需要将所有行视为一个组。因此,请考虑group by。 。 。以及条件:

select md.idMembre
from membres_has_domaines md
where md.idDomaine not in (40) 
group by md.idMembre 
having sum( md.idDomaine in (40) ) = 0;

having子句计算与条件匹配的每个成员的行数。 = 0表示成员没有行。

请注意,我已将联接移至membres。根据您的示例数据和查询,查询不需要它。如果你想要其他列,那么它应该是查询的一部分。

答案 2 :(得分:1)

因为您还有以下记录:

idMembre  idDomaine
1         10
1         11
3         22

因此,在声明分组之前,您将获得下一个结果:

 idMembre  idDomaine
 1         10
 1         11
 2         10
 2         13
 2         20
 3         22