DevGang
Авторизоваться

Использование SQLite для изучения связей между данными и сравнения таблиц

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

  • INNER JOIN
  • LEFT JOIN
  • Использование нескольких операторов соединения

И запросы SQLite, которые можно использовать для сравнения таблиц:

  • INTERSECT
  • UNION
  • UNION ALL
  • EXCEPT

Простые запросы выбора

Чтобы проиллюстрировать, как использовать операторы SELECT, я создал базу данных для отслеживания садовых растений и грядок, на которые я ссылаюсь в примерах, которые использую. В базе данных есть таблица растений, содержащая информацию о различных садовых растениях, включая название растения, требует ли оно солнечного света и время года, когда растение начинает цвести. Данные в таблице растений можно получить с помощью запроса SELECT:

SELECT * FROM plants;
id  name              full_sun  bloom      
--  ----------------  --------  -----------
1   Bee Balm          0         late spring
2   Petunia           1         summer     
3   Coneflower        0         summer     
4   Zinnia            1         late spring
5   Black-Eyed Susan  0         summer  

В столбце full_sun целые числа 1 и 0 используются для представления логических значений 'true' и 'false' соответственно.

Чтобы ограничить столбцы результатов включением только идентификационного номера и названия растения, столбцы можно указать в инструкции SELECT вместо использования *:

SELECT * FROM plants WHERE full_sun IS 0;
id  name              full_sun  bloom      
--  ----------------  --------  -----------
1   Bee Balm          0         late spring
3   Coneflower        0         summer     
5   Black-Eyed Susan  0         summer 

Выбор запросов с операторами соединения

Извлечение данных из одной таблицы имеет свои применения, но оно не позволяет мне легко увидеть связи между данными в нескольких таблицах. Вы можете использовать операторы соединения для одновременного просмотра данных в нескольких таблицах.

В нашей базе данных также есть таблица с информацией по грядкам:

beds

id  light        
--  -------------
1   full sun     
2   partial shade

Один и тот же тип растения можно посадить на нескольких грядках, а на грядке может быть несколько видов растений. Чтобы отслеживать взаимоотношения между растениями и грядками, существует таблица соединений, называемая plant_beds:

plant_beds

id  plant_id  bed_id
--  --------  ------
1   1         2     
2   4         1     
3   3         2     
4   5         1     
5   1         1 

Взаимосвязь между таблицами plants, beds и plant_beds можно визуализировать следующим образом:

INNER JOIN

INNER JOIN можно использовать для просмотра растений, соответствующих каждой строке таблицы соединения plant_bed. SQLite обрабатывает операторы «INNER JOIN», «JOIN» и «,» одинаково, поэтому их можно использовать как взаимозаменяемые.

SELECT plant_beds.id, plant_beds.plant_id, plants.name, plant_beds.bed_id
FROM plant_beds
INNER JOIN plants
ON plant_beds.plant_id = plants.id
id  plant_id  name              bed_id
--  --------  ----------------  ------
1   1         Bee Balm          2     
2   4         Zinnia            1     
3   3         Coneflower        2     
4   5         Black-Eyed Susan  1     
5   1         Bee Balm          1

Не забудьте включить в запрос оператор ON. Оператор ON сообщает SQLite, как таблицы связаны друг с другом. Без этой инструкции SQLite вернет каждую строку из таблицы plant_beds, совпадающую с каждой строкой из базы данных растений:

SELECT plant_beds.id, plant_beds.plant_id, plants.name, plant_beds.bed_id
FROM plant_beds
INNER JOIN plants
id  plant_id  name              bed_id
--  --------  ----------------  ------
1   1         Bee Balm          2     
1   1         Petunia           2     
1   1         Coneflower        2     
1   1         Zinnia            2     
1   1         Black-Eyed Susan  2     
2   4         Bee Balm          1     
2   4         Petunia           1     
2   4         Coneflower        1     
2   4         Zinnia            1     
2   4         Black-Eyed Susan  1     
3   3         Bee Balm          2     
3   3         Petunia           2     
3   3         Coneflower        2     
3   3         Zinnia            2     
3   3         Black-Eyed Susan  2     
4   5         Bee Balm          1     
4   5         Petunia           1     
4   5         Coneflower        1     
4   5         Zinnia            1     
4   5         Black-Eyed Susan  1     
5   1         Bee Balm          1     
5   1         Petunia           1     
5   1         Coneflower        1     
5   1         Zinnia            1     
5   1         Black-Eyed Susan  1  

Этот результат включает в ответ петунии, хотя в настоящее время они не связаны ни с одной грядкой в ​​нашей соединительной таблице plant_beds. Таким образом, хотя SQLite вернул информацию как из таблицы Plants, так и из таблицы Plant_beds, ответ не отражает связь между двумя таблицами.

LEFT JOIN

Ответ на запрос INNER JOIN включает только те строки из каждой таблицы, которые соответствуют оператору ON. Итак, в приведенном выше примере Петуния не включается в ответ, поскольку она не включена в таблицу plant_beds. Чтобы просмотреть все строки из левой или правой таблицы, вместо INNER JOIN следует использовать LEFT JOIN или LEFT OUTER JOIN. Ответ на запрос LEFT JOIN будет включать в себя те же строки, что и запрос INNER JOIN, а также дополнительную строку из каждой строки в левой таблице (или первой таблице, указанной в запросе), которая не имеет соответствующей строки в правая таблица (вторая таблица, указанная в запросе). SQLite использует NULL в качестве значения по умолчанию для любого столбца, который не имеет значения в правой таблице.

SELECT plant_beds.id, plant_beds.plant_id, plants.name, plant_beds.bed_id
FROM plant_beds
LEFT JOIN plants
ON plant_beds.plant_id = plants.id
id  plant_id  name              bed_id
--  --------  ----------------  ------
5   1         Bee Balm          1     
1   1         Bee Balm          2     
              Petunia                 
3   3         Coneflower        2     
2   4         Zinnia            1     
4   5         Black-Eyed Susan  1 

Как видно из этого примера, результат запроса LEFT JOIN включает строку Petunia из таблицы Plants и использует значения NULL, которые отображаются в виде пробелов, для столбцов, где нет соответствия для Petunia в таблице plant_beds.

Использование оператора JOIN с более чем двумя таблицами

Операторы INNER JOIN и LEFT JOIN могут повторяться в запросе для получения результата, включающего информацию из более чем одной таблицы. Например, чтобы просмотреть информацию из таблицы plant_beds, а также сведения из таблиц Plant_beds, можно использовать два оператора INNER JOIN.

SELECT plant_beds.id, plant_beds.plant_id, plants.name, plant_beds.bed_id, beds.light
FROM plant_beds
INNER JOIN plants
ON plant_beds.plant_id = plants.id
INNER JOIN beds
ON plant_beds.bed_id = beds.id
id  plant_id  name              bed_id  light        
--  --------  ----------------  ------  -------------
1   1         Bee Balm          2       partial shade
2   4         Zinnia            1       full sun     
3   3         Coneflower        2       partial shade
4   5         Black-Eyed Susan  1       full sun     
5   1         Bee Balm          1       full sun 

Составные операторы выбора

Что, если вместо того, чтобы перечислять все растения в одной таблице, растения были отсортированы по нескольким таблицам на основе характеристик каждого растения? Я составил еще три таблицы базы данных, чтобы отслеживать местные растения, растения, которые особенно привлекательны для пчел, и растения, которые могут привлечь колибри. Конечно, есть местные растения, которые хорошо подходят для пчел и колибри, поэтому в трех таблицах есть некоторые общие растения.

native_plants

id  name                full_sun  bloom      
--  ------------------  --------  -----------
1   Arrowwood Viburnum  0         late spring
2   Bee Balm            0         late spring
3   Black-Eyed Susan    0         summer     
4   Coneflower          0         summer     
5   Goldenrod           0         late summer

bee_plants

id  name        full_sun  bloom      
--  ----------  --------  -----------
1   Bee Balm    0         late spring
2   Lavender    1         summer     
3   Coneflower  0         summer     
4   Zinnia      1         late spring

hummingbird_plants

id  name             full_sun  bloom      
--  ---------------  --------  -----------
1   Petunia          1         summer     
2   Bee Balm         0         late spring
3   Cardinal Flower  1         mid summer 
4   Garden Phlox     0         summer 

Эти таблицы также можно визуализировать следующим образом:

Теперь, когда растения организованы в несколько таблиц, было бы неплохо иметь возможность сравнивать таблицы друг с другом. Это можно сделать с помощью составных операторов SELECT. В частности, с операторами INTERSECT, UNION, UNION ALL и EXCEPT.

INTERSECT

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

SELECT name, bloom FROM native_plants
INTERSECT
SELECT name, bloom FROM bee_plants
name        bloom      
----------  -----------
Bee Balm    late spring
Coneflower  summer

Чтобы запрос INTERSECT работал, столбцы в каждом столбце SELECT должны совпадать. Операторы SELECT должны иметь одинаковое количество столбцов, и столбцы должны возвращать один и тот же тип информации, чтобы SQLite мог сравнивать значения каждого столбца.

Обратите внимание, что в этом примере инструкция SELECT не использует id или * для получения столбца id из таблиц. Хотя таблицы Native_plants, bee_plants и hummingbird_plants имеют некоторые общие растения, эти растения не имеют одинаковых идентификационных номеров в каждой таблице. В bee_plants идентификатор Bee Balm равен 1, а Coneflower — 3, тогда как в Native_plants Bee Balm имеет идентификатор 2, а Coneflower — идентификатор 4. Таким образом, если запрос включал столбец id, Bee Balm и Coneflower строки из каждой таблицы не будут совпадать, и оператор INTERSECT не вернет никаких результатов.

UNION или UNION ALL

Чтобы получить информацию из нескольких таблиц, независимо от того, одинаковы ли строки в каждой таблице, используйте оператор UNION.

SELECT name, bloom FROM bee_plants
UNION
SELECT name, bloom FROM hummingbird_plants
name             bloom      
---------------  -----------
Bee Balm         late spring
Cardinal Flower  mid summer 
Coneflower       summer     
Garden Phlox     summer     
Lavender         summer     
Petunia          summer     
Zinnia           late spring

Оператор UNION вернул строки из таблицы bee_plants и строки из таблицы hummingbird_plants и автоматически удалил повторяющиеся строки. Чтобы вернуть каждую строку из обеих таблиц, даже если строка присутствует в каждой таблице, можно использовать оператор UNION ALL.

SELECT name, bloom FROM bee_plants
UNION ALL
SELECT name, bloom FROM hummingbird_plants
name             bloom      
---------------  -----------
Bee Balm         late spring
Lavender         summer     
Coneflower       summer     
Zinnia           late spring
Petunia          summer     
Bee Balm         late spring
Cardinal Flower  mid summer 
Garden Phlox     summer 

Пчелиный бальзам появляется дважды в результате запроса UNION ALL, поскольку он существует как в таблице hummingbird_plants, так и в таблице bee_plants.

EXCEPT

Оператор EXCEPT можно использовать для извлечения строк из одной таблицы, которые не отображаются в другой таблице.

SELECT name, bloom FROM native_plants
EXCEPT
SELECT name, bloom FROM bee_plants
name                bloom      
------------------  -----------
Arrowwood Viburnum  late spring
Black-Eyed Susan    summer     
Goldenrod           late summer

Заключение

Подробную документацию по операторам SELECT SQLite, включая описанные выше операторы и многие другие варианты построения оператора SELECT, можно найти на веб-сайте SQLite.

Источник:

#SQL
Комментарии
Чтобы оставить комментарий, необходимо авторизоваться

Присоединяйся в тусовку

В этом месте могла бы быть ваша реклама

Разместить рекламу