Странное с LEFT JOIN

pilot911

Новичок
Странное с LEFT JOIN

Пытаюсь сделать выборку из связанных таблицы:

таблица цен
таблица товаров

То есть выбрать записи типов цен для данного товара


вот два скриншота запросов и результата выборки:






разница лишь в WHERE goods_id=1 и 2

как я понимаю, из таблицы типов цен должны выбираться все записи - однако для товара с ид=1 выбирается одна запись, а для ид=2, как и полагается, все 3

В чем может быть дело ?
 

DiMA

php.spb.ru
Команда форума
по-моему, тебе нужно выспаться .-)
с первым запросом все нормально - выбирается один нулл, т.е. в базе нет строк с "1"
 

pilot911

Новичок
мне кажется, что выбираться должны все типы цен, разве нет?

почему тогда при ид=2 выбираются все 3 типа цены, хотя товару привязаны только два типа ?
 

pilot911

Новичок
вот засада, вроде все правильно делаю - первая (левая) таблица - должны выбираться все записи, верно?

или я что-то путаю в основе ?
 

zerkms

TDD infected
Команда форума
pilot911
чтобы дали совет - нужно формулировать начальную задачу в терминах предметной области + приложить к ней схему БД. а не давать неработающие запросы и спрашивать, что в них не так.

вот засада, вроде все правильно делаю - первая (левая) таблица - должны выбираться все записи, верно?
верно. убери WHERE и будут выбираться все записи из левой таблицы.
 

pilot911

Новичок
структура простая

ТАБЛИЦА тип_цены {
ид,
название
}

ТАБЛИЦА тип_цены_продукт {
ид,
ид_продукта,
ид_тип_цены
}

мне надо в одном запросе вывести все записи из таблицы "тип_цены", и, если для продукта указан тип цены - вывести ид продукта


то есть, как это бывает с LEFT JOIN - левая таблица должна выводиться полностью в любом случае
 

pilot911

Новичок
zerkms, спасибо за совет

я написал в WHERE


WHERE goods_id=1 OR goods_id IS NULL


как я понимаю, IS NULL позволяет вывести из таблицы "тип_цены" все типы цен, разве нет ?
 

zerkms

TDD infected
Команда форума
pilot911
IS NULL позволяет выбрать записи, для которых не сработало условие в ON (и был возвращён ряд NULL'ов)
 

pilot911

Новичок
спасибо, zerkms, разобрался

необходимо делать различия между ON и WHERE

WHERE применяет фильтр уже к сформированному объединению, тогда как ON применяет фильтр к только создаваемому объединению и поэтому нужно в ON указать, что объединять нужно и те строки, которые имеют NULL во второй (правой) таблице


то есть запрос выглядит так:


SELECT *
FROM тип_цены
LEFT JOIN тип_цены_продукт
ON
тип_цены.ид = тип_цены_продукт.тип_ид
AND
(продукт_ид = 1 OR продукт_ид IS NULL)
 

zerkms

TDD infected
Команда форума
pilot911
тогда зачем ты поместил это условие в ON? :)
 

pilot911

Новичок
:) потому что иначе вместо всех записей, которые есть в таблице "тип цены", выводится только одна ....

я сам удивлен, вроде левая таблица д выводиться полностью, ан нет ...
 

zerkms

TDD infected
Команда форума
pilot911
не верю
предикат OR FALSE (а у тебя там false, сам сказал) не должно оказывать никакого влияния
 

iceman

говнокодер
извиняюсь, если не правильно понял вопроса
мне надо в одном запросе вывести все записи из таблицы "тип_цены", и, если для продукта указан тип цены - вывести ид продукта
тип_цен - справочник, как для него можно вывести ид_продукта (если их там много?), т.е связь идет от тип_цены_продукта к тип_цены
 

shark_255

Новичок
SELECT *
FROM тип_цены
LEFT JOIN тип_цены_продукт
ON
тип_цены.ид = тип_цены_продукт.тип_ид
AND
(продукт_ид = 1 OR продукт_ид IS NULL)
а как это стыкуется с условием
http://www.mysql.ru/docs/man/JOIN.html

Никогда не следует указывать в части ON какие бы то ни было условия, накладывающие ограничения на строки в наборе результатов. Если необходимо указать, какие строки должны присутствовать в результате, следует сделать это в выражении WHERE.
?

Есть ли какие-нибудь ссылки на первоисточники, как правильно работают условия, определенные после ON в JOIN-e ?
 
Сверху