Запрос Mysql NOT IN не возвращает то, что я хочу

0

Думаю, я что-то не понимаю, но у меня очень странный результат, а не в.

У меня есть такие таблицы

Табличные мембраны

idMembre
1
2
...

Табличные мембраны_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 в этом результате?

большое спасибо за вашу помощь

EDIT: после первого ответа я понимаю проблему... на самом деле моя просьба намного сложнее. Я работаю над полной динамической системой фильтрации, созданной формой 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

note... этот запрос не выполняет работу по той же причине моего первоначального упрощенного примера.

я не знаю, могу ли я сделать это без использования предложения или подзапросов... это довольно сложно. Я думаю, подзапросы - единственный способ? что ты думаешь?...

  • 1
    Поскольку у вас есть записи для всех трех пользователей с записями, отличными от 40, вы можете просмотреть их, если вы используете Select * без «Group by»
  • 3
    Потому что строки существуют там, где idMembre in (1, 3) и idDomaine not in (40) . Вы, вероятно, ищете NOT EXISTS .
Теги:
notin

3 ответа

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
    );
  • 0
    да, я думаю, что это может быть решением ... но если возможно, я бы хотел избежать генерации подзапросов ... потому что я нахожусь на полной динамической системе, и это действительно сложно ... например, я могу иметь много параметров, используя просил те же ссылки (см. мой оригинальный пост обновления и пример).
  • 0
    Еще раз спасибо. После обжига моего мозга ... я внес изменения в свой сценарий, чтобы он работал таким образом;) Кажется, он работает сейчас ... но я должен проверить много случаев для ферментации. Спасибо за вашу помощь
1

Поскольку у вас также есть записи как:

idMembre  idDomaine
1         10
1         11
3         22

Поэтому перед группой по заявлению вы получите следующий результат:

 idMembre  idDomaine
 1         10
 1         11
 2         10
 2         13
 2         20
 3         22
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. Учитывая ваши данные образца и запрос, он не нужен для запроса. Если вам нужны другие столбцы, то это должно быть частью запроса.

  • 0
    Привет. спасибо за ваш ответ ... Я должен подумать о том, как реализовать это в моей системе. Я создал полностью динамическую систему фильтров, автоматически сгенерированную формой ... и на самом деле есть много других параметров, которые можно запрашивать ... Реальный пример - я хочу найти членов с доменом в (1,2,3 ) за исключением тех, у кого есть домены в (4,5) ...
  • 0
    я отредактирую свой пост, чтобы показать конкретный пример.
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню