SQLinfo.ru - Все о MySQL

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 21.05.2011 00:38:25

FiMko
Активист
Откуда: Санкт-Петербург
Зарегистрирован: 18.09.2009
Сообщений: 198

Не могу разобраться с работой JOIN

Ребята, привет всем! Помогите пожалуйста разобраться в работе JOIN.

Имеются две таблицы:

mysql> DESCRIBE word_forms;
+----------+---------+------+-----+---------+-------+
| Field    | Type    | Null | Key | Default | Extra |
+----------+---------+------+-----+---------+-------+
| group_id | int(11) | NO   |     | 0       |       |
| word_id  | int(11) | NO   | MUL | NULL    |       |
+----------+---------+------+-----+---------+-------+

mysql> SELECT * FROM word_forms;
+----------+---------+
| group_id | word_id |
+----------+---------+
|        1 |      38 |
|        0 |      31 |
+----------+---------+

mysql> DESCRIBE phrases;
+-----------+---------------------+------+-----+---------+-------+
| Field     | Type                | Null | Key | Default | Extra |
+-----------+---------------------+------+-----+---------+-------+
| phrase_id | int(11) unsigned    | NO   | MUL | NULL    |       |
| word_id   | int(11) unsigned    | NO   | MUL | NULL    |       |
| order_id  | tinyint(4) unsigned | NO   |     | NULL    |       |
+-----------+---------------------+------+-----+---------+-------+

mysql> SELECT * FROM phrases;
+-----------+---------+----------+
| phrase_id | word_id | order_id |
+-----------+---------+----------+
|         1 |      31 |        1 |
|         2 |      32 |        1 |
|         4 |      34 |        1 |
|         5 |      35 |        1 |
|         6 |      38 |        1 |
|         7 |      39 |        1 |
|         8 |      40 |        1 |
|         9 |      41 |        1 |
|        10 |      42 |        1 |
|        11 |      43 |        1 |
|        12 |      44 |        1 |
|        13 |      45 |        1 |
|        14 |      31 |        1 |
|        14 |      39 |        2 |
+-----------+---------+----------+

Имеется первый запрос:

SELECT
    DISTINCT phrases.phrase_id
FROM phrases
    JOIN word_forms AS wf1 ON wf1.word_id IN (39)
    JOIN word_forms AS wf ON (wf.group_id BETWEEN wf1.group_id - (wf1.group_id MOD 100) AND (wf1.group_id - (wf1.group_id MOD 100)) + 99)
    WHERE phrases.word_id IN (39) OR phrases.word_id = wf.word_id;

Empty set (0.00 sec)

С другой стороны если просто пишу:

SELECT
    DISTINCT phrases.phrase_id
FROM phrases
    WHERE phrases.word_id IN (39);

то выборка есть:

+-----------+
| phrase_id |
+-----------+
|         7 |
|        14 |
+-----------+

Не могу понять почему такое поведение (пустой результат) для первого запроса, почему эти два JOIN'а оказывают подобное "исключающее" влияние на результат выборки?

Отредактированно FiMko (21.05.2011 00:58:16)

Неактивен

 

#2 21.05.2011 13:25:43

FiMko
Активист
Откуда: Санкт-Петербург
Зарегистрирован: 18.09.2009
Сообщений: 198

Re: Не могу разобраться с работой JOIN

Как-то вот так вот работает:

SELECT
    DISTINCT phrases.phrase_id
FROM phrases
    WHERE phrases.word_id IN (31)
UNION SELECT
    DISTINCT phrases.phrase_id
FROM phrases
    JOIN word_forms AS wf1 ON wf1.word_id IN (31)
    JOIN word_forms AS wf ON (wf.group_id BETWEEN wf1.group_id - (wf1.group_id MOD 100) AND (wf1.group_id - (wf1.group_id MOD 100)) + 99)
    WHERE phrases.word_id = wf.word_id;

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

Неактивен

 

#3 21.05.2011 17:23:19

FiMko
Активист
Откуда: Санкт-Петербург
Зарегистрирован: 18.09.2009
Сообщений: 198

Re: Не могу разобраться с работой JOIN

Хмм, с LEFT JOIN все работает:

SELECT
    DISTINCT phrases.phrase_id
FROM phrases
    LEFT JOIN word_forms AS wf1 ON wf1.word_id IN (39)
    LEFT JOIN word_forms AS wf ON (wf.group_id BETWEEN wf1.group_id - (wf1.group_id MOD 100) AND (wf1.group_id - (wf1.group_id MOD 100)) + 99)
    WHERE phrases.word_id IN (39) OR phrases.word_id = wf.word_id;
+-----------+
| phrase_id |
+-----------+
|         7 |
|        14 |
+-----------+

Разбираюсь почему...

Неактивен

 

#4 21.05.2011 19:22:43

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Не могу разобраться с работой JOIN

JOIN требует наличия соответствующих строк в присоединяемых таблицах.
Если строк нет, то и выборка оказывается пустой.

Неактивен

 

#5 21.05.2011 20:45:59

FiMko
Активист
Откуда: Санкт-Петербург
Зарегистрирован: 18.09.2009
Сообщений: 198

Re: Не могу разобраться с работой JOIN

paulus написал:

JOIN требует наличия соответствующих строк в присоединяемых таблицах.
Если строк нет, то и выборка оказывается пустой.

Это правда, но...

http://s58.radikal.ru/i161/1105/f1/ef0a710ae26b.png
Пусть два JOIN'а и не дали результата и результирующая их выборка оказалась пустой, почему при этом другая подчасть первого запроса, выделенная красным не сработала, ведь именно она же дает не пустой результат если ее изолировать от JOIN'ов (второй запрос)?

Отредактированно FiMko (21.05.2011 21:04:53)

Неактивен

 

#6 21.05.2011 23:20:32

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Не могу разобраться с работой JOIN

Пусть у Вас есть две библиотеки. В случае без JOIN запрос звучит так:
«найди мне книги, которые есть в первой библиотеке, у которых автор
Марк Твен». Запрос с JOIN звучит так: «найди мне книги, которые есть
в обеих библиотеках, у которых автор Марк Твен или написано слово
″Твен″ в названии». Даже если будет много «или» — при пустой второй
библиотеке счастья не будет smile

Неактивен

 

#7 21.05.2011 23:34:23

FiMko
Активист
Откуда: Санкт-Петербург
Зарегистрирован: 18.09.2009
Сообщений: 198

Re: Не могу разобраться с работой JOIN

paulus написал:

Запрос с JOIN звучит так: «найди мне книги, которые есть
в обеих библиотеках, у которых автор Марк Твен или написано слово
″Твен″ в названии».

paulus, cпасибо за помощь (всегда выручаете)! Почему-то для этого случая я ошибочно в голове представлял, что JOIN объединяет (как для union) выборки и поэтому отсутствие в одной из выборок результата не должно повлечь исключения рядом стоящего другого непустого результата. Теперь стало понятно почему LEFT JOIN помог.

Отредактированно FiMko (21.05.2011 23:40:51)

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson