Несогласованные результаты подзапроса IN и NOT IN - PullRequest
0 голосов
/ 11 декабря 2018

У меня есть три таблицы: пациенты, чаты и salesforce_leads.Я хочу найти все электронные письма в чатах, которых нет в двух других таблицах.Моя первая попытка вернула 0, и я очень озадачен, почему.Ниже приведены запросы и их результаты:

Запрос 1: Первая попытка с неожиданными результатами

SELECT CouNT(DISTINCT LOWER(chat_email)) FROM chats 
WHERE LOWER(chat_email) NOT IN (
 SELECT LOWER(email) FROM patients 
 UNION ALL 
 SELECT LOWER(lead_email) FROM salesforce_leads)
[ { 'COUNT(DISTINCT LOWER(chat_email))': 0 } ]

Результат: 0

Естественно неудовлетворен этимответ, я попробовал следующее:

Запрос 2: Сколько существует в обоих?

SELECT CouNT(DISTINCT LOWER(chat_email)) FROM chats 
WHERE LOWER(chat_email) IN (
 SELECT LOWER(email) FROM patients 
 UNION ALL
 SELECT LOWER(lead_email) FROM salesforce_leads)
[ { 'COUNT(DISTINCT LOWER(chat_email))': 701 } ]

Результат: 701

Запрос3: Сколько уникальных писем?

SELECT COUNT(DISTINCT LOWER(chat_email)) FROM chats
[ { 'COUNT(DISTINCT LOWER(chat_email))': 1059 } ]

Результат: 1059

Так что я бы ожидал, что результат запроса 1 будет 358 (1059 - 701).Я наконец смог получить этот результат, выполнив запрос 4 ниже, но я не понимаю, почему.

Запрос 4: достигает ожидаемого результата, но он не симпатичен и использует дополнительный подзапрос.

SELECT CouNT(DISTINCT LOWER(chat_email)) FROM chats 
WHERE LOWER(chat_email) NOT IN (
 SELECT DISTINCT(LOWER(chat_email)) FROM chats 
 WHERE LOWER(chat_email) IN (
  SELECT LOWER(email) FROM patients 
  UNION ALL 
  SELECT LOWER(lead_email) FROM salesforce_leads))
[ { 'COUNT(DISTINCT LOWER(chat_email))': 358 } ]

Может кто-нибудь объяснить мне, почему запрос 1 может не совпадать с результатом запроса 4?

Это использует node.js и sqlite3.

Ответы [ 2 ]

0 голосов
/ 14 декабря 2018

Вы предполагаете, что NOT IN не работает должным образом?Потому что в последнее время у меня сложилось впечатление, что это может быть так.В моем случае (ранее обсуждалось в ветке несколько недель назад, которую я еще не нашел), Я искал article_revisions, которые были бы NOT IN таблицей articles ... noteчто ни одно из этих значений не является NULL ... и я всегда придумываю «ничего», что неверно.

В то время как запрос IN выдает список значений, которые действительно совпадают.

Итак - по крайней мере, мне кажется - IN работает, но NOT IN нет.

Гордон, это тоже ваш опыт?Вы говорите, что я должен попробовать NOT EXISTS?

0 голосов
/ 12 декабря 2018

Никогда использовать NOT IN с подзапросами.Это не ведет себя так, как вы ожидаете.Если какое-либо значение, возвращаемое в подзапросе, равно NULL, то все строки отфильтровываются.

Вместо этого используйте NOT EXISTS:

SELECT COUNT(DISTINCT LOWER(c.chat_email))
FROM chats c
WHERE NOT EXISTS (SELECT 1 FROM patients p WHERE LOWER(p.email) = LOWER(c.chat_email)
                 ) AND
      NOT EXISTS (SELECT 1 FROM salesforce_leads sf WHERE LOWER(sf.email) = LOWER(c.chat_email)
                 ) ;

Я разбил логику на два подзапроса, простопотому что использование union / union all в таких подзапросах обычно мешает оптимизации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...