2016-01-25 5 views
0

У меня есть две таблицы:MySQL JOIN независимо от ИНЕКЕ

debates 
---------------------- 
id | name 
---------------------- 
1 | why is that? 
2 | why is the other? 

opinions 
--------------------- 
id | debate | opinion 
--------------------- 
1 | 1  | because 
2 | 1  | NULL 

Если я использую покинул присоединитьсяON opinions.debate = debates.id я могу получить обе дискуссии (1, 2).

Если я использую где положение на верхней части влево присоединитьсяWHERE (opinions.opinion! = '' И opinions.opinion IS NOT NULL) я получаю только дискутировать с ид = 1

Как можно получить обе записи, но все же сохранить условие, потому что я использую его для подсчета записей?

ex. запрос:

SELECT 

debates.id, 
COUNT(opinions.id) AS total_opinions 

FROM debates 

LEFT JOIN 
`opinions` ON `opinions`.`debate` = `debates`.`id` 

WHERE 
`opinions`.`opinion` IS NOT NULL AND `opinions`.`opinion` != '' 

GROUP BY 
`debates`.`id` 

Если вернуться:

debates 
------------------- 
id | total_opinions 
------------------- 
1 | 1 
2 | 0 
+0

Ну как вы могли получить дебаты 2 вы настаиваете на том, что ** мнений.опиньон НЕ НУЛЛ **? Точка левого соединения в первую очередь - это ПОЗВОЛЯТЬ мнений. ПРОТИВ БЫТЬ НУЛЛ, чтобы появилось обсуждение 2. –

ответ

1

Цель LEFT OUTER JOIN, чтобы разрешить все строки одной таблицы в списке, даже если эти строки не ссылки в другой таблице, и если существуют такие условия, вы получаете NULL значения из этой другой таблицы , Таким образом, чтобы получить все дебаты, даже если там не было ни одного мнения некоторых из них вы можете сделать это:

FROM debates 
LEFT OUTER JOIN `opinions` ON `opinions`.`debate` = `debates`.`id` 

Когда нет мнения по дискуссии все позиции столбцов для данных в таблице мнения будет NULL

Если вы подсчитываете количество мнений, то важно отметить, что функция COUNT() ТОЛЬКО увеличивается на 1, если значение NON NULL. Следовательно, следующее автоматически подсчитывает правильное количество мнений без необходимости отфильтровывать NULL.

SELECT 
     debates.id 
    , COUNT(opinions.id) AS total_opinions 
FROM debates 
LEFT OUTER JOIN `opinions` ON `opinions`.`debate` = `debates`.`id` 
GROUP BY 
     debates.id 

Теперь, если у вас действительно есть строки в таблице мнения, где мнение является пустой строкой вы можете так это:

SELECT 
     debates.id 
    , COUNT(opinions.id) AS total_opinions 
FROM debates 
LEFT OUTER JOIN `opinions` ON `opinions`.`debate` = `debates`.`id` 
          AND `opinions`.`opinion` <> '' 
GROUP BY 
     debates.id 

или:

SELECT 
     debates.id 
    , COUNT(case when `opinions`.`opinion` <> '' then opinions.id end) AS total_opinions 
FROM debates 
LEFT OUTER JOIN `opinions` ON `opinions`.`debate` = `debates`.`id` 
GROUP BY 
     debates.id 
+0

Спасибо за ответ. Решение @Giorgos Betsos было точно таким же. –

+0

Не то же самое. Перемещение всех предикатов в соединение не требовалось. Просто нет необходимости фильтровать для NULL, если вы считаете, например. –

+0

Вы более чем правы. Условие ** IS NOT NULL ** не является необходимым и фактически является излишком. –

3

Перемещение предикаты оговорки WHERE к ON:

SELECT debates.id, 
     COUNT(opinions.id) AS total_opinions  
FROM debates  
LEFT JOIN `opinions` 
ON `opinions`.`debate` = `debates`.`id` AND 
    `opinions`.`opinion` IS NOT NULL AND 
    `opinions`.`opinion` != ''  
GROUP BY `debates`.`id` 

Этот запрос будет получать все записи debates, соединенные записи opinions, которые удовлетворяют условиям, указанным в ON предикаты. Если нет совпадения, возвращается NULL, который будет проигнорирован как совокупная функция COUNT.

Demo here

+0

Я не знал, что инструкции ON могут получить дополнительные условия, а не отношения соединения. Благодарю. –

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

  • Нет связанных вопросов^_^