142 / 142 / 27
Регистрация: 19.12.2011
Сообщений: 250
1

Описание оператора JOIN

08.02.2013, 23:10. Показов 42971. Ответов 16
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
MySQL оператор JOIN

Часто вижу на форуме проблемы связанные с объединением в одном запросе данных из нескольких таблиц. Например:
  • как одним запросом достать список категорий, и количество статей в каждой категории?
  • как одним запросом достать два уровня каталога с указанием родителя каждой категории?
  • как одним запросом достать название товара и описание к нему, если они лежать в разных таблицах?
В этом посте мы научимся все это делать, и многое другое.


Содержание

Введение
INNER (CROSS) JOIN
Используем USING
Используем ON
LEFT JOIN
RIGHT JOIN
Многотабличные запросы


Введение
Для начала нам нужен некий набор таблиц, на которых мы будем ставить эксперименты. Я выбрал четыре до безобразия простых таблицы:
SQL
1
2
3
4
5
6
7
8
9
10
mysql> SHOW TABLES;
+----------------+
| Tables_in_test |
+----------------+
| catalogue      |
| item           |
| item_desc      |
| item_price     |
+----------------+
4 ROWS IN SET (0.00 sec)
Каталог наших товаров
SQL
1
2
3
4
5
6
7
8
9
mysql> SELECT * FROM `catalogue`;
+----+-----------+------------------------------------------------------+
| id | parent_id | catalogue_name                                       |
+----+-----------+------------------------------------------------------+
|  1 |         0 | Телевизоры LED, ЖК, плазменные                       |
|  2 |         0 | DVD и Blu-ray плееры                                 |
|  3 |         1 | Кронштейны и подставки                               |
+----+-----------+------------------------------------------------------+
3 ROWS IN SET (0.00 sec)
Собственно сами товары:
SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
mysql> SELECT * FROM `item`;
+----+--------------+--------------------------------------------------------------------------------+
| id | catalogue_id | item_name                                                                      |
+----+--------------+--------------------------------------------------------------------------------+
|  1 |            1 | плазменный телевизор LG 42PA4510                                               |
|  2 |            1 | ЖК-телевизор Philips 46PFL5507T/60                                             |
|  3 |            2 | Портативный DVD-плеер Mystery MPS-108 Black                                    |
|  4 |            2 | DVD-плеер Fusion FD-U157X Black                                                |
|  5 |            2 | Blu-ray-плеер Samsung BD-E5300                                                 |
|  6 |            2 | Проигрыватель Samsung BD-E5500 Black                                           |
|  7 |            3 | Кронштейн для ЖК и плазм Holder PTS-4006 металлик                              |
|  8 |            3 | Кронштейн для ЖК и плазм Holder LCDS-5004 металлик                             |
+----+--------------+--------------------------------------------------------------------------------+
8 ROWS IN SET (0.00 sec)
Описание товаров
SQL
1
2
3
4
5
6
7
8
9
mysql> SELECT * FROM `item_desc`;
+----+------------------------------------------+
| id | item_description                         |
+----+------------------------------------------+
|  2 | Хорошо показывает                        |
|  5 | Читает много форматов                    |
|  9 | не известный товар                       |
+----+------------------------------------------+
3 ROWS IN SET (0.00 sec)
Цены на товары.
SQL
1
2
3
4
5
6
7
8
9
10
11
mysql> SELECT * FROM `item_price`;
+---------+-------+
| item_id | price |
+---------+-------+
|       1 | 15890 |
|       2 | 31990 |
|       5 |  3190 |
|       7 |  1800 |
|       8 |   850 |
+---------+-------+
5 ROWS IN SET (0.00 sec)
Обратите внимание, цены и описания установлены не на все товары.


В зависимости от наших запросов, мы будем использовать три способа соединения таблиц:
  • INNER (CROSS) JOIN - внутреннее (перекрёстное) объединение
  • LEFT JOIN - левостороннее внешнее объединение
  • RIGHT JOIN - правостороннее внешнее объединение


INNER (CROSS) JOIN
Это объединение извлекает строки, которые обязательно присутствуют в объединяемых таблицах.
Без указания условий отбора, выборка вернет декартово произведение, где каждая строка одной таблицы будет сопоставлена с каждой строкой другой таблицы:
SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
mysql> SELECT * FROM `item`
    -> INNER JOIN `item_desc`;
+----+--------------+--------------------------------------------------------------------------------+----+------------------------------------------+
| id | catalogue_id | name                                                                           | id | description                              |
+----+--------------+--------------------------------------------------------------------------------+----+------------------------------------------+
|  1 |            1 | плазменный телевизор LG 42PA4510                                               |  2 | Хорошо показывает                        |
|  1 |            1 | плазменный телевизор LG 42PA4510                                               |  5 | Читает много форматов                    |
|  1 |            1 | плазменный телевизор LG 42PA4510                                               |  9 | не известный товар                       |
|  2 |            1 | ЖК-телевизор Philips 46PFL5507T/60                                             |  2 | Хорошо показывает                        |
|  2 |            1 | ЖК-телевизор Philips 46PFL5507T/60                                             |  5 | Читает много форматов                    |
|  2 |            1 | ЖК-телевизор Philips 46PFL5507T/60                                             |  9 | не известный товар                       |
|  3 |            2 | Портативный DVD-плеер Mystery MPS-108 Black                                    |  2 | Хорошо показывает                        |
|  3 |            2 | Портативный DVD-плеер Mystery MPS-108 Black                                    |  5 | Читает много форматов                    |
|  3 |            2 | Портативный DVD-плеер Mystery MPS-108 Black                                    |  9 | не известный товар                       |
|  4 |            2 | DVD-плеер Fusion FD-U157X Black                                                |  2 | Хорошо показывает                        |
|  4 |            2 | DVD-плеер Fusion FD-U157X Black                                                |  5 | Читает много форматов                    |
|  4 |            2 | DVD-плеер Fusion FD-U157X Black                                                |  9 | не известный товар                       |
|  5 |            2 | Blu-ray-плеер Samsung BD-E5300                                                 |  2 | Хорошо показывает                        |
|  5 |            2 | Blu-ray-плеер Samsung BD-E5300                                                 |  5 | Читает много форматов                    |
|  5 |            2 | Blu-ray-плеер Samsung BD-E5300                                                 |  9 | не известный товар                       |
|  6 |            2 | Проигрыватель Samsung BD-E5500 Black                                           |  2 | Хорошо показывает                        |
|  6 |            2 | Проигрыватель Samsung BD-E5500 Black                                           |  5 | Читает много форматов                    |
|  6 |            2 | Проигрыватель Samsung BD-E5500 Black                                           |  9 | не известный товар                       |
|  7 |            3 | Кронштейн для ЖК и плазм Holder PTS-4006 металлик                              |  2 | Хорошо показывает                        |
|  7 |            3 | Кронштейн для ЖК и плазм Holder PTS-4006 металлик                              |  5 | Читает много форматов                    |
|  7 |            3 | Кронштейн для ЖК и плазм Holder PTS-4006 металлик                              |  9 | не известный товар                       |
|  8 |            3 | Кронштейн для ЖК и плазм Holder LCDS-5004 металлик                             |  2 | Хорошо показывает                        |
|  8 |            3 | Кронштейн для ЖК и плазм Holder LCDS-5004 металлик                             |  5 | Читает много форматов                    |
|  8 |            3 | Кронштейн для ЖК и плазм Holder LCDS-5004 металлик                             |  9 | не известный товар                       |
+----+--------------+--------------------------------------------------------------------------------+----+------------------------------------------+
24 ROWS IN SET (0.00 sec)
Такое соединение таблиц редко нужно, чаще требуется выбрать только сопоставленные записи. Делается это установкой условия отбора, используя ON или USING

Используем USING
SQL
1
2
3
4
5
6
7
8
9
mysql> SELECT * FROM `item` 
    -> INNER JOIN `item_desc` USING (`id`);
+----+--------------+------------------------------------------------+------------------------------------------+
| id | catalogue_id | item_name                                      | item_description                         |
+----+--------------+------------------------------------------------+------------------------------------------+
|  2 |            1 | ЖК-телевизор Philips 46PFL5507T/60             | Хорошо показывает                        |
|  5 |            2 | Blu-ray-плеер Samsung BD-E5300                 | Читает много форматов                    |
+----+--------------+------------------------------------------------+------------------------------------------+
2 ROWS IN SET (0.00 sec)
Запрос вернул только те записи, которые имеют одинаковые идентификаторы в обеих таблицах.
Мы использовали USING, потому что в обоих таблицах ключевой столбец имеет одно и тоже имя - id.

Используем ON
SQL
1
2
3
4
5
6
7
8
9
10
11
12
mysql> SELECT * FROM `item` `i`  
    -> INNER JOIN `item_price` `ip` ON `i`.`id`=`ip`.`item_id`;
+----+--------------+--------------------------------------------------------------------------------+---------+-------+
| id | catalogue_id | item_name                                                                      | item_id | price |
+----+--------------+--------------------------------------------------------------------------------+---------+-------+
|  1 |            1 | плазменный телевизор LG 42PA4510                                               |       1 | 15890 |
|  2 |            1 | ЖК-телевизор Philips 46PFL5507T/60                                             |       2 | 31990 |
|  5 |            2 | Blu-ray-плеер Samsung BD-E5300                                                 |       5 |  3190 |
|  7 |            3 | Кронштейн для ЖК и плазм Holder PTS-4006 металлик                              |       7 |  1800 |
|  8 |            3 | Кронштейн для ЖК и плазм Holder LCDS-5004 металлик                             |       8 |   850 |
+----+--------------+--------------------------------------------------------------------------------+---------+-------+
5 ROWS IN SET (0.00 sec)
Обратите внимание, во втором примере я использовал синонимы (alias) для имен таблиц:
  • `i` - для item
  • `ip` - для item_price
Синонимы можно также использовать и для столбцов в выборке:
SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
mysql> SELECT `i`.`id`, `i`.`item_name`, `ip`.`price` 
    -> FROM `item` AS `i`  
    -> INNER JOIN `item_price` AS `ip` ON `i`.`id`=`ip`.`item_id`;
+----+--------------------------------------------------------------------------------+-------+
| id | item_name                                                                      | price |
+----+--------------------------------------------------------------------------------+-------+
|  1 | плазменный телевизор LG 42PA4510                                               | 15890 |
|  2 | ЖК-телевизор Philips 46PFL5507T/60                                             | 31990 |
|  5 | Blu-ray-плеер Samsung BD-E5300                                                 |  3190 |
|  7 | Кронштейн для ЖК и плазм Holder PTS-4006 металлик                              |  1800 |
|  8 | Кронштейн для ЖК и плазм Holder LCDS-5004 металлик                             |   850 |
+----+--------------------------------------------------------------------------------+-------+
5 ROWS IN SET (0.00 sec)
Обратите внимание, в этот раз я использовал [AS] для указания синонимов, а в предыдущем варианте его не было. Оба варианта верные, и можно использовать любой вариант. Какой ближе, тот и используйте. Лично я не указываю [AS], экономлю время
36
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
08.02.2013, 23:10
Ответы с готовыми решениями:

Особенности оператора Join
Приветствую. В запросе мне необходимо выбрать данные из нескольких таблиц. Когда я подключаю...

Запросы RIGHT JOIN и LEFT JOIN в чём различие?
Добрый день! Чем отличаются запросы RIGHT JOIN и LEFT JOIN, если они выдают один и тот же результат?

Необычный join (применить условие where для первой таблицы, а потом where для результата join)
мне нужно прежде чем джоинить, применить условие where для первой таблицы. а потом where для...

Ошибка "Integrity constraint violation" при запросе INNER JOIN LEFT JOIN
это запрос на вывод категорий в каждой категории есть файлы и для каждой категории я хочу вывести...

16
142 / 142 / 27
Регистрация: 19.12.2011
Сообщений: 250
08.02.2013, 23:10  [ТС] 2
Конструкцию INNER JOIN можно объявить так же через CROSS JOIN, JOIN и запятую в объявлении FROM. Следующие запросы вернут один и тот же результат:
SQL
1
2
3
4
mysql> SELECT * FROM `item` INNER JOIN `item_desc`;
mysql> SELECT * FROM `item` CROSS JOIN `item_desc`;
mysql> SELECT * FROM `item` JOIN `item_desc`;
mysql> SELECT * FROM `item`, `item_desc`;
Если объединять таблицы через запятую, то нельзя использовать ON или USING. Условие должно задаваться только в конструкции WHERE. Например:
SQL
1
2
3
4
5
6
7
8
9
mysql> SELECT * FROM `item`, `item_desc` 
    -> WHERE `item`.`id` = `item_desc`.`id`;
+----+--------------+------------------------------------------------+----+------------------------------------------+
| id | catalogue_id | item_name                                      | id | item_description                         |
+----+--------------+------------------------------------------------+----+------------------------------------------+
|  2 |            1 | ЖК-телевизор Philips 46PFL5507T/60             |  2 | Хорошо показывает                        |
|  5 |            2 | Blu-ray-плеер Samsung BD-E5300                 |  5 | Читает много форматов                    |
+----+--------------+------------------------------------------------+----+------------------------------------------+
2 ROWS IN SET (0.00 sec)
В данном случае, поле id присутствует в обеих таблицах, поэтому нужно уточнить в каком контексте оно используется путем указания имен таблиц.

MySQL позволяет объединять таблицу саму с собой. Но в этом случае необходимо следить за синонимами таблиц, если они будут неоднозначны, то запрос не будет выполнен, так как совпадут названия полей.
Например, если таблицу catalogue просто объединить саму на себя, то возникнет конфликт имен:
SQL
1
2
3
mysql> SELECT * FROM `catalogue` 
    -> JOIN `catalogue`;
ERROR 1066 (42000): NOT UNIQUE TABLE/alias: 'catalogue'
С использованием синонимов запрос успешно выполнится:
SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
mysql> SELECT * FROM `catalogue` `c1` 
    -> JOIN `catalogue` `c2`;
+----+-----------+------------------------------------------------------+----+-----------+------------------------------------------------------+
| id | parent_id | catalogue_name                                       | id | parent_id | catalogue_name                                       |
+----+-----------+------------------------------------------------------+----+-----------+------------------------------------------------------+
|  1 |         0 | Телевизоры LED, ЖК, плазменные                       |  1 |         0 | Телевизоры LED, ЖК, плазменные                       |
|  2 |         0 | DVD и Blu-ray плееры                                 |  1 |         0 | Телевизоры LED, ЖК, плазменные                       |
|  3 |         1 | Кронштейны и подставки                               |  1 |         0 | Телевизоры LED, ЖК, плазменные                       |
|  1 |         0 | Телевизоры LED, ЖК, плазменные                       |  2 |         0 | DVD и Blu-ray плееры                                 |
|  2 |         0 | DVD и Blu-ray плееры                                 |  2 |         0 | DVD и Blu-ray плееры                                 |
|  3 |         1 | Кронштейны и подставки                               |  2 |         0 | DVD и Blu-ray плееры                                 |
|  1 |         0 | Телевизоры LED, ЖК, плазменные                       |  3 |         1 | Кронштейны и подставки                               |
|  2 |         0 | DVD и Blu-ray плееры                                 |  3 |         1 | Кронштейны и подставки                               |
|  3 |         1 | Кронштейны и подставки                               |  3 |         1 | Кронштейны и подставки                               |
+----+-----------+------------------------------------------------------+----+-----------+------------------------------------------------------+
9 ROWS IN SET (0.00 sec)
LEFT JOIN
Левостороннее объединение позволяет получить данные из таблиц, дополняя их по возможности данными из другой таблицы. В отличие от INNER(CROSS) JOIN при объединении LEFT JOIN обязательным является условие, которое задается через ON или USING. Без него интерпретатор MySQL будет выдавать ошибку.
Сейчас мы получим полный список товаров вместе с их описанием, независимо от того есть описание к товару или нет:
SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
mysql> SELECT * FROM `item` 
    -> LEFT JOIN `item_desc` USING (`id`);
+----+--------------+--------------------------------------------------------------------------------+------------------------------------------+
| id | catalogue_id | item_name                                                                      | item_description                         |
+----+--------------+--------------------------------------------------------------------------------+------------------------------------------+
|  1 |            1 | плазменный телевизор LG 42PA4510                                               | NULL                                     |
|  2 |            1 | ЖК-телевизор Philips 46PFL5507T/60                                             | Хорошо показывает                        |
|  3 |            2 | Портативный DVD-плеер Mystery MPS-108 Black                                    | NULL                                     |
|  4 |            2 | DVD-плеер Fusion FD-U157X Black                                                | NULL                                     |
|  5 |            2 | Blu-ray-плеер Samsung BD-E5300                                                 | Читает много форматов                    |
|  6 |            2 | Проигрыватель Samsung BD-E5500 Black                                           | NULL                                     |
|  7 |            3 | Кронштейн для ЖК и плазм Holder PTS-4006 металлик                              | NULL                                     |
|  8 |            3 | Кронштейн для ЖК и плазм Holder LCDS-5004 металлик                             | NULL                                     |
+----+--------------+--------------------------------------------------------------------------------+------------------------------------------+
8 ROWS IN SET (0.00 sec)
Так как не для всех наименований есть описания, то в поле description появился NULL.
Таким приемом можно воспользоваться чтобы найти все товары без описания, если дополнить предыдущий запрос условием на проверку отсутствия описания:
SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
mysql> SELECT `id`, `item_name` 
    -> FROM `item` 
    -> LEFT JOIN `item_desc` USING (`id`) 
    -> WHERE `item_description` IS NULL;
+----+--------------------------------------------------------------------------------+
| id | item_name                                                                      |
+----+--------------------------------------------------------------------------------+
|  4 | DVD-плеер Fusion FD-U157X Black                                                |
|  8 | Кронштейн для ЖК и плазм Holder LCDS-5004 металлик                             |
|  7 | Кронштейн для ЖК и плазм Holder PTS-4006 металлик                              |
|  1 | плазменный телевизор LG 42PA4510                                               |
|  3 | Портативный DVD-плеер Mystery MPS-108 Black                                    |
|  6 | Проигрыватель Samsung BD-E5500 Black                                           |
+----+--------------------------------------------------------------------------------+
6 ROWS IN SET (0.00 sec)


RIGHT JOIN
RIGHT JOIN практически ничем не отличается от LEFT JOIN, кроме того, что сначала данные берутся из второй таблицы, которая находится справа от конструкции JOIN, и сравниваются с данными, которые находятся в таблице, указанной перед конструкцией.
SQL
1
2
3
4
5
6
7
8
9
10
mysql> SELECT * FROM `item` 
    -> RIGHT JOIN `item_desc` USING (`id`);
+----+------------------------------------------+--------------+------------------------------------------------+
| id | item_description                         | catalogue_id | item_name                                      |
+----+------------------------------------------+--------------+------------------------------------------------+
|  2 | Хорошо показывает                        |            1 | ЖК-телевизор Philips 46PFL5507T/60             |
|  5 | Читает много форматов                    |            2 | Blu-ray-плеер Samsung BD-E5300                 |
|  9 | не известный товар                       |         NULL | NULL                                           |
+----+------------------------------------------+--------------+------------------------------------------------+
3 ROWS IN SET (0.00 sec)
Обратите внимание, теперь поля catalogue_id и item_name содержат нулевые значения.

Из выше приведенного примера очевидно, что следующие запросы вернут идентичный результат:
SQL
1
2
mysql> SELECT * FROM `item` LEFT JOIN `item_desc` USING (`id`);
mysql> SELECT * FROM `item_desc` RIGHT JOIN `item` USING (`id`);

Многотабличные запросы
С помощью JOIN, можно объединять не только две таблицы, как мы делали выше, а гораздо больше. Кроме того, MySQL не накладывает ограничений на использование разных типов объединений в одном запросе, поэтому можно формировать довольно сложные конструкции:
SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
mysql> SELECT `c`.`catalogue_name`, `i`.`item_name`, `ip`.`price`, `id`.`item_description` 
    -> FROM `catalogue` `c` 
    -> INNER JOIN `item` `i` ON `i`.`catalogue_id` = `c`.`id` 
    -> INNER JOIN `item_price` `ip` ON `ip`.`item_id` = `i`.`id` 
    -> LEFT JOIN `item_desc` `id` ON `i`.`id` = `id`.`id`;
+------------------------------------------------------+--------------------------------------------------------------------------------+-------+------------------------------------------+
| catalogue_name                                       | item_name                                                                      | price | item_description                         |
+------------------------------------------------------+--------------------------------------------------------------------------------+-------+------------------------------------------+
| Телевизоры LED, ЖК, плазменные                       | плазменный телевизор LG 42PA4510                                               | 15890 | NULL                                     |
| Телевизоры LED, ЖК, плазменные                       | ЖК-телевизор Philips 46PFL5507T/60                                             | 31990 | Хорошо показывает                        |
| DVD и Blu-ray плееры                                 | Blu-ray-плеер Samsung BD-E5300                                                 |  3190 | Читает много форматов                    |
| Кронштейны и подставки                               | Кронштейн для ЖК и плазм Holder PTS-4006 металлик                              |  1800 | NULL                                     |
| Кронштейны и подставки                               | Кронштейн для ЖК и плазм Holder LCDS-5004 металлик                             |   850 | NULL                                     |
+------------------------------------------------------+--------------------------------------------------------------------------------+-------+------------------------------------------+
5 ROWS IN SET (0.00 sec)
В данном случае мы одним запросом получили список категорий со всеми товарами, на которые установлены цены. Так же проверили на каких товарах есть описания, чтобы сразу их вывести тоже.


Заключение
Завершить хочется цитатой американского философа
Трудности существуют для того, чтобы преодолевать их.
Р. Эмерсон
JOIN'ы только на первый взгляд страшные и не понятные

Удачи вам в любых начинаниях
7
25 / 25 / 4
Регистрация: 21.10.2012
Сообщений: 391
08.02.2013, 23:27 3
Интересный пост) Будем вникать!) Спасибо
2
1 / 1 / 0
Регистрация: 15.04.2010
Сообщений: 38
07.03.2014, 12:47 4
Суперовый мануал, но хотелось бы дополнения: как на счет JOIN-ить таблицу из другой БД?
0
142 / 142 / 27
Регистрация: 19.12.2011
Сообщений: 250
07.03.2014, 12:58  [ТС] 5
Цитата Сообщение от emptyxl Посмотреть сообщение
как на счет JOIN-ить таблицу из другой БД?
Все намного проще, чем кажется)
SQL
1
2
3
4
5
mysql> SELECT `c`.`catalogue_name`, `i`.`item_name`, `ip`.`price`, `id`.`item_description` 
    -> FROM `database1`.`catalogue` `c` 
    -> INNER JOIN `database2`.`item` `i` ON `i`.`catalogue_id` = `c`.`id` 
    -> INNER JOIN `database3`.`item_price` `ip` ON `ip`.`item_id` = `i`.`id` 
    -> LEFT JOIN `database4`.`item_desc` `id` ON `i`.`id` = `id`.`id`;
Цитата Сообщение от emptyxl Посмотреть сообщение
Суперовый мануал, но хотелось бы дополнения
обязательно дополню
0
1 / 1 / 0
Регистрация: 15.04.2010
Сообщений: 38
11.03.2014, 11:58 6
Все работает, только Front кавычки не воспринимает.
Плюсанул!
1
60 / 55 / 20
Регистрация: 01.04.2013
Сообщений: 551
17.03.2014, 14:43 7
Хорошая статья , в копилку !
1
0 / 0 / 0
Регистрация: 28.11.2013
Сообщений: 3
05.04.2014, 20:23 8
Полезный мануал, но мне не помог. Никак не могу сделать запрос.
Суть в следующем: есть две таблицы с одинаковыми полями, необходимо получить все строки с двух таблиц у которых поле `user_id` равно какому-то числу.
Например в табл. 1 есть три записи, у одной из них поле user_id=35, и табл. 2 в ней три записи и две из них имеют user_id=35, как получить все записи из табл. 1 и 2 где user_id=35?

Подскажите как составить запрос SELECT.
0
142 / 142 / 27
Регистрация: 19.12.2011
Сообщений: 250
05.04.2014, 20:29  [ТС] 9
Вам наверно стоит посмотреть в сторону UNION
1
0 / 0 / 0
Регистрация: 28.11.2013
Сообщений: 3
05.04.2014, 20:44 10
Ладно, пойду дальше бороздить просторы мануала SQL....
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
16.06.2014, 17:55 11
А что в MySQL нет полного связывания?
(Когда и "слева" и "справа" может не быть соответствия ?)
0
311 / 271 / 118
Регистрация: 05.06.2013
Сообщений: 868
30.10.2014, 18:04 12
Я думаю тут не хватает этого изображения:

12
16 / 16 / 10
Регистрация: 16.06.2014
Сообщений: 180
20.04.2015, 02:27 13
Я поверхносто уже знаком с JOINами и заметил, что в первом примере(inner join) результат будет другим. Там почему то игнорируется 3-я строка из таблицы item_desc "не известный товар". Чтобы проверить не ошибаюсь ли я,я создал точно такие таблицы и заполнил их. При запросе
SQL
1
2
SELECT * FROM `item` 
    -> INNER JOIN `item_desc`;
выводится 24 строки. Или я что то не правильно делаю?
1
142 / 142 / 27
Регистрация: 19.12.2011
Сообщений: 250
24.04.2015, 09:42  [ТС] 14
4unkur, спасибо за внимательность.
BRcr, спасибо за помощь в исправлении ошибки. INNER JOIN
1
22 / 22 / 9
Регистрация: 16.03.2015
Сообщений: 193
13.10.2015, 14:42 15
Спасибо за статью, очень помогла в составлении сложного запроса! В копилку)
2
94 / 94 / 68
Регистрация: 26.03.2015
Сообщений: 248
18.06.2016, 08:04 16
Jefe, кстати, в MySQL нет оператора FULL OUTER JOIN. Его альтернативой в данной СУБД является конструкция из двух SELECT'ов, объединенных оператором UNION.

Таким образом, код
SQL
1
2
3
4
SELECT <select_list>
FROM TableA A
FULL OUTER JOIN TableB B
ON A.`Key`=B.`Key`;
можно заменить на
SQL
1
2
3
4
5
6
7
8
9
SELECT <select_list>
    FROM TableA A
    LEFT JOIN TableB B
    ON A.`Key`=B.`Key`
UNION
SELECT <select_list>
    FROM TableA A
    RIGHT JOIN TableB B
    ON A.`Key`=B.`Key`;
А код
SQL
1
2
3
4
5
6
SELECT <select_list>
FROM TableA A
FULL OUTER JOIN TableB B
ON A.`Key`=B.`Key`
WHERE A.`Key` IS NULL
OR B.`Key` IS NULL;
на
SQL
1
2
3
4
5
6
7
8
9
10
11
SELECT <select_list>
    FROM TableA A
    LEFT JOIN TableB B
    ON A.`Key`=B.`Key`
    WHERE B.`Key` IS NULL
UNION
SELECT <select_list>
    FROM TableA A
    RIGHT JOIN TableB B
    ON A.`Key`=B.`Key`
    WHERE A.`Key` IS NULL;
0
6 / 23 / 2
Регистрация: 29.01.2013
Сообщений: 174
19.05.2018, 12:25 17
Не получается вывести из левой таблицы (rajon) все записи (из второй берется только количество определенных записей). В Результате из левой таблицы выводятся только записи которые результат которых справа отличен от NULL.

$sql="SELECT `rajon`.`nzv`, COUNT(`klient`.`pib`) FROM `rajon` LEFT OUTER JOIN `klient` ON `klient`.`rn`=`rajon`.`id` GROUP BY `klient`.`rn` ORDER BY `rajon`.`id` ASC";

Подскажите, что не так?
0
19.05.2018, 12:25
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
19.05.2018, 12:25
Помогаю со студенческими работами здесь

Join описание на php
перерыл много страниц по описанию работы JOIN и везде указано как сам запрос в mysql делать но не...

Подскажите, где найти описание join hints
Я имею ввиду hash, merge и loop join. Подскажите, где можно прочесть, что эти хинты значат? Как...

Описание оператора в классе
есть класс, там есть массив, задача добавить в конец элемент class IntSet { private: int...

Посмотрите описание конструктора копирования и оператора присваивания с ними все в порядке? После функции add теряются данные
class Person{ char *name; int age; char *floor; char *phone; public: Person(){...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru