2013-02-13 4 views
1

У меня есть две таблицы и вы хотите объединить их вместе таким образом, чтобы исключить все значения во второй таблице. Когда я присоединяюсь к обеим таблицам, мне нужны только значения в таблице 1, и мне не нужны значения в обеих таблицах или значения только в таблице 2.JOIN - Исключить все значения во второй таблице

Я думал, что это будет сделано с ЛЕВОЙ ВСТУПИЛ ИЛИ ВЛЕВО Присоединяйтесь, но я нахожу некоторые странные выводы.

Когда я проверяю все данные, у меня есть следующий счетчик.

-- TOTAL LEADS: 10067 
SELECT COUNT(*) FROM sold_leads AS sl 
WHERE sl.affiliate_id IN(1000,1001,1002,1033) 
AND sl.create_date >= '2013-1-1' 
AND sl.lead_type = 'AUTO'; 

Однако, когда я пытаюсь найти только значения только в таблице 1, я нахожу большее число, что просто невозможно.

-- How many had No suspension/dui, sr22, and <=2 accidents AND <=2 tickets: 13931 
SELECT COUNT(*) FROM sold_leads AS sl 
INNER JOIN drivers AS dr ON sl.lead_id = dr.lead_id 
LEFT OUTER JOIN duis AS duis ON sl.lead_id = duis.driver_id 
LEFT OUTER JOIN accidents AS ac ON sl.lead_id = ac.driver_id 
WHERE sl.affiliate_id IN(1000,1001,1002,1033) 
AND sl.create_date >= '2013-1-1' 
AND dr.relationship_type = 'SELF'; 

Там нет никакого способа, что общее количество будет меньше, чем кол, где я оставил присоединиться несколько таблиц и добавить некоторые ограничения. Что я делаю не так.

Кроме того, я знаю, что я не представил схему, но как бы выбрать только < = 2 несчастных случая. Существует таблица аварий, в которой есть driver_id, но я играл с различными вариациями HAVING (COUNT (*)) и не повезло.

Помогите !?

+0

Сложно сказать, без данных выборки, но довольно легко получить больше записей, когда вы присоединитесь. Возможно, вы должны сделать 'COUNT (DISTINCT sl.affiliate_id)' вместо 'count (*)' –

ответ

2

Исключение присоединяется, как правило, условием, что ограничивает результаты тех, где это не матч внешнего соединения таблицы:

SELECT COUNT(*) FROM sold_leads AS sl 
INNER JOIN drivers AS dr ON sl.lead_id = dr.lead_id 
LEFT OUTER JOIN duis AS duis ON sl.lead_id = duis.driver_id 
LEFT OUTER JOIN accidents AS ac ON sl.lead_id = ac.driver_id 
WHERE sl.affiliate_id IN(1000,1001,1002,1033) 
AND sl.create_date >= '2013-1-1' 
AND dr.relationship_type = 'SELF' 
-- these are the exclusion join tests: 
AND duis.driver_id IS NULL AND ac.driver_id IS NULL 

Также комментарий от @ConradFrix хорошо; если у вас есть> 1 строка в drivers за строку в sold_leads, вы можете получить мультипликативные эффекты, поэтому лучше вернуться COUNT(DISTINCT sl.something), где что-то - уникальная колонка.

Я также не очень уверен в ваших условиях соединения, вы сравниваете duis.driver_id и ac.driver_id с sl.lead_id. Но dr.lead_id также сравнивается с sl.lead_id. Неправильно ли это или другое из этих условий? Конечно, вы знаете свою схему лучше, чем я, но похоже, что имена столбцов непоследовательны.

1

Если drivers, duis или accidents имеет более чем один ряд с тем же lead_id, то ваш результат будет иметь более чем одну строку с тем же lead_id, и вы увеличите общее количество строк. Вы, вероятно, имел в виду, чтобы добавить к вашей ИНЕКЕ:

AND  duis.lead_id IS NULL 
AND  ac.lead_id IS NULL 

Если вы хотите только sold_leads, которые не имеют записи соответствия в duis или accidents, то это может быть понятнее использовать NOT IN и подзапрос вместо присоединения непосредственно к этим таблицам. Вы можете увидеть некоторые примеры и обсуждение некоторых альтернатив в this question.

Смежные вопросы