Различия
Показаны различия между двумя версиями страницы.
Следующая версия | Предыдущая версия | ||
sql:mysql:join [2015/09/26 13:30] – создано - внешнее изменение 127.0.0.1 | sql:mysql:join [2024/10/30 20:31] (текущий) – mirocow | ||
---|---|---|---|
Строка 3: | Строка 3: | ||
====== Join / Sql / database ====== | ====== Join / Sql / database ====== | ||
+ | {{: | ||
- | Имеем две таблицы | + | ===== JOINS ===== |
- | + | === author === | |
- | U) users D) departments | + | |
- | id name | + | |
- | -- ---- | + | |
- | 1 Владимир | + | |
- | 2 Антон | + | |
- | 3 Александр | + | |
- | 4 Борис | + | |
- | 5 Юрий | + | |
- | + | ||
+ | ^ id ^ name ^ | ||
+ | | 1 | Вася | ||
+ | | 2 | Коля | ||
+ | | 3 | Петя | ||
- | + | === util === | |
- | < | + | |
- | SELECT u.id, u.name, d.name AS d_name | + | |
- | FROM users u | + | |
- | INNER JOIN departments d ON u.d_id | + | |
- | </ | + | |
- | + | ||
+ | ^ id ^ author_id | ||
+ | | 1 | 1 | Вася Мега продукт | ||
+ | | 2 | 0 | Крутая, | ||
- | Запрос вернет объединенные данные, | + | ===== SQL INNER / INNER JOIN - естественное |
- | - пользователь Александр (отдел 6) | + | |
- | - отдел Финансы (нет пользователей) | + | |
- | + | Возвращает записи, у которых есть соответствующие записи в обеих таблицах. | |
- | id name | + | |
- | -- -------- | + | |
- | 1 | + | |
- | 2 Антон Поддержка | + | |
- | 4 Борис Поддержка | + | |
- | 3 Юрий | + | |
- | + | ||
+ | <code sql> | ||
+ | -- Выводим все поля | ||
+ | select * | ||
+ | -- Указываем таблицу авторов | ||
+ | from author | ||
+ | -- Соединяем с таблицей программ | ||
+ | inner join util | ||
+ | -- Указываем условие | ||
+ | on author.id = util.author_id | ||
+ | </ | ||
+ | ^ id ^ name | id | author_id | ||
+ | | 1 | Вася | ||
- | {{: | + | ===== LEFT JOIN ===== |
- | рис. | + | Возвращает все записи из левой таблицы и соответствующие записи из правой таблицы. Если соответствия нет, возвращает NULL для правой таблицы. |
- | INNER JOIN это синоним для JOIN. Выбираются только совпадающие данные из объединяемых таблиц. Чтобы получить данные, которые не подходят по условию, необходимо использовать OUTER JOIN. Такое объединение вернет данные из обеих таблиц совпадающими по одному из условий. | + | <code sql> |
+ | -- Выводим все поля | ||
+ | select * | ||
+ | -- Указываем таблицу авторов | ||
+ | from author | ||
+ | -- Соединяем с таблицей программ | ||
+ | left join util | ||
+ | -- Указываем условие | ||
+ | on author.id = util.author_id | ||
+ | </ | ||
+ | ^ id ^ name | id | author_id | ||
+ | | 1 | Вася | ||
+ | | 2 | Коля | ||
+ | | 3 | Петя | ||
- | {{: | + | ===== RIGHT JOIN ===== |
- | рис. | + | Возвращает все записи из правой таблицы и соответствующие записи из левой таблицы. Если соответствия нет, возвращает NULL для левой таблицы. |
- | Существует | + | <code sql> |
- | + | -- Выводим все поля | |
- | + | select * | |
- | < | + | -- Указываем таблицу авторов |
- | SELECT u.id, u.name, d.name AS d_name | + | from author |
- | FROM users u | + | -- Соединяем с таблицей |
- | LEFT OUTER JOIN departments d ON u.d_id | + | right join util |
+ | -- Указываем | ||
+ | on author.id = util.author_id | ||
</ | </ | ||
- | |||
+ | ^ id ^ name | id | author_id | ||
+ | | 1 | Вася | ||
+ | | NULL | NULL | 2 | 0 | Крутая, | ||
- | Получаем полный список пользователей и сопоставленные департаменты. | + | ===== LEFT OUTER JOIN - левое внешнее соединение ===== |
- | + | Возвращает все записи из левой таблицы и соответствующие записи из правой таблицы. Если соответствия нет, возвращает NULL для правой таблицы. | |
- | id name d_name | + | |
- | -- -------- | + | |
- | 1 Владимир Сейлз | + | |
- | 2 Антон Поддержка | + | |
- | 3 | + | |
- | 4 Борис Поддержка | + | |
- | 5 Юрий Логистика | + | |
- | | + | |
- | {{:sql: | + | < |
- | рис. Left outer join с фильтрацией по полю | ||
- | |||
- | RIGHT OUTER JOIN вернет полный список департаментов (правая таблица) и сопоставленных пользователей. | ||
- | |||
- | |||
- | < | ||
- | SELECT u.id, u.name, d.name AS d_name | ||
- | FROM users u | ||
- | RIGHT OUTER JOIN departments d ON u.d_id = d.id | ||
- | WHERE u.id IS NULL | ||
</ | </ | ||
- | |||
+ | ===== RIGHT OUTER JOIN - правое внешнее соединение ===== | ||
- | + | Возвращает все записи из правой таблицы и соответствующие записи из левой таблицы. Если соответствия нет, возвращает NULL для левой таблицы. | |
- | id name d_name | + | |
- | -- -------- | + | |
- | 1 Владимир Сейлз | + | |
- | 2 Антон Поддержка | + | |
- | 4 | + | |
- | NULL NULL Финансы | + | |
- | 5 Юрий Логистика | + | |
- | | + | |
+ | <code sql> | ||
- | Дополнительно можно отфильтровать данные, | + | </ |
- | В нашем примере указав WHERE u.id IS null, мы отбросим записи, | + | |
- | Информация: | + | ===== FULL JOIN - полное внешнее соединение ===== |
- | * http:// | + | |
- | * http:// | + | |
- | * http:// | + | |
- | * http:// | + | |
- | * http:// | + | |
+ | Возвращает все записи, | ||
- | ====== Self joins ====== | + | <code sql> |
+ | </ | ||
- | Так называемая выборка с замыканием на себя (и совсем не closure). Нужна нам, если необходимо выбрать более одного | + | ===== CROSS JOIN - перекрестное или декартово соединение |
- | значения из таблицы для нескольких условий. | + | |
- | + | ||
- | Имеем: набор фильтров для информации, | + | |
- | Необходимо: фильтровать продукты по дате, артикулу и имеющимся фильтрам | + | |
- | + | ||
- | + | ||
- | <code php> | + | |
- | CREATE TABLE filts_data | + | |
- | ( | + | |
- | id serial NOT NULL, | + | |
- | fid integer NOT NULL, -- product_item.id | + | |
- | value integer NOT NULL, -- значение | + | |
- | pid integer NOT NULL -- фильтр filts.id | + | |
- | ) | + | |
- | </ | + | |
- | + | ||
- | + | ||
- | + | ||
- | Есть таблица условных товаров product_item | + | |
- | + | ||
- | + | ||
- | < | + | |
- | CREATE TABLE product_item | + | |
- | ( | + | |
- | id serial NOT NULL, | + | |
- | section_id integer, | + | |
- | date timestamp, | + | |
- | art text, | + | |
- | title text | + | |
- | ) | + | |
- | </ | + | |
- | + | ||
+ | Выполняет декартово произведение двух таблиц, | ||
- | Пример: | + | <code sql> |
- | Логика подскажет нам такой запрос (нерабочий): | + | |
- | < | ||
- | SELECT p1.title FROM products_item p1 INNER JOIN filts_data p2 ON p1.id = p2.fid | ||
- | WHERE p1.date > ' | ||
</ | </ | ||
+ | ===== UNIOUN ===== | ||
- | Этот запрос не найдет элементов в таблице. | + | <code sql> |
- | Перепишем запрос, | + | |
- | < | ||
- | SELECT p1.* FROM product_item p1 INNER JOIN filts_data p2 ON p1.id = p2.fid | ||
</ | </ | ||
- | В этом случае мы получим записи, | ||