Программирование >>  Исключение дубликатов строк 

1 ... 85 86 87 [ 88 ] 89 90 91 ... 152


Еще раз рассмотрим таблицы Recipes и Recipe Classes. Для данного примера предположим, что нас интересуют только виды Salads (Салаты), Soups (Супы) и Main courses (Главные блюда). Вот запрос с использованием таблицы Recipe Classes, отфильтрованной в операторе SELECT, который является частью INNER JOIN:

SQL SELECT RCFiltered.ClassName, R.RecipeTitle

FROM

(SELECT RecipeClassID, RecipeClassDescription AS ClassName

FROM RecipeClasses AS RC WHERE RC.ClassName = Salads OR RC.ClassName = Soup

OR RC.ClassName = Main Course) AS RCFiltered

LEFT OUTER JOIN Recipes AS R

ON RCFiltered.RecipeClassID = R.RecipeClassID

Будьте осторожны при использовании оператора SELECT в условии FROM. В первую очередь, когда принимается решение заменить оператор SELECT на имя таблицы, обязательно нужно включить не только столбцы, которые должны присутствовать в окончательном результате, но также все связывающие столбцы, необходимые для выполнения JOIN. Именно поэтому во вложенном операторе присутствуют как RecipeClassID, так и RecipeClassDescription. Просто для шутки присвоим RecipeClassDescription псевдоним ClassName во вложенном операторе. В результате условие SELECT запрашивает ClassName, а не RecipeClassDescription. Условие ON ссылается теперь на корреляционное имя вложенного оператора SELECT - RCFiltered - вместо исходного имени таблицы или корреляционного имени, присвоенного таблице во вложенном операторе SELECT.

Если данный запрос выполнить для реального примера базы данных Recipes, то получим одну строку с RecipeClassDescription для Soup со значением Null, возвращенным для RecipeTitle, потому что в этом примере базы данных рецепты супов отсутствуют. Также легко можно было бы построить оператор SELECT по таблице Recipes в правой части OUTER JOIN. Например, можно запросить все рецепты, содержащие слово beef (говядина) в своем заголовке:

SQL SELECT RCFiltered.ClassName, R.RecipeTitle

FROM

(SELECT RecipeClassID, RecipeClassDescription AS ClassName

FROM RecipeClasses AS RC WHERE RC.ClassName = Salads OR RC.ClassName = Soup

OR RC.ClassName = Main Course) AS RCFiltered LEFT OUTER JOIN (SELECT Recipes.RecipeClassID, Recipes.RecipeTitle



FROM Recipes

WHERE Recipes.RecipeTitle LIKE XbeefX) AS R ON RCFiltered.RecipeClassID = R.RecipeClassID

LEFT OUTER JOIN запрашивает все строки из набора результатов или таблицы, указанной в левой части JOIN, независимо от того, суш,ествуют ли строки, удов-летворяюш,ие условию, в правой части. Предыдуш,ий запрос не только возвраш,ает строку Soup со значением Null в RecipeTitle (поскольку в базе данных вообш,е отсутствуют рецепты супов), но также и строку Salad со значением Null. Можно было бы предположить, что в базе данных также отсутствуют и рецепты салатов, но фактически они там есть, только отсутствуют салаты с beef в заголовке рецепта!

Внимание! Возможно, вы обратили внимание, что можно ввести полное условие поиска как часть условия ON в JOIN. Совершенно правильно, поэтому вполне законно по стандарту SQL решить приведенную выше задачу следуюш,им образом:

SELECT Recipe Classes.RecipeClassDescription,

Recipes.RecipeTitle FROM RecipeClasses LEFT OUTER JOIN Recipes

ON Recipe Classes.RecipeClassID = Recipes.RecipeClassID AND

(Recipe.Classes.RecipeClassDescription = Salads

OR Recipe Classes.RecipeClassDescription = OR RecipeClasses.RecipeClassDescription = AND Recipes.RecipeTitle LIKE %beef%

Soup

Main Course)

К сожалению, некоторые основные реализации SQL решают эту задачу неверно или вообш,е не воспринимают этот синтаксис! Поэтому рекомендуется всегда указывать в условии поиска условия ON только такие критерии, которые сравнивают столбцы из двух таблиц или наборов результатов. Если нужно отфильтровать строки из базовых таблиц, делайте это в отдельном условии поиска в условии WHERE во вложенном операторе SELECT.

вложение условий JOIN в условия JOIN

Хотя многие задачи можно решить, просто связывая две таблицы, очень часто требуется связать три, четыре или более таблиц, чтобы получить все данные, необходимые для решения запроса. Например, может потребоваться извлечь всю существенную информацию о рецептах - тип рецепта, название рецепта и все компоненты для него - в одном запросе. Зная, как использовать OUTER JOIN, можно также получить список всех видов рецептов - даже тех, для которых пока



Ingredients

IngredfentlD

IngredientName

ingredienlQassID

MeasureAmountlD


......ME/WUREMENIS......!\

MeasureAmountID PK Measu rementDescriptton

REClPEjNOREOrENTS

RedpelD PK

RecipeSeqNo PK

IngredienUD FK

MeasureAmounllD FK Amount

Recipes

Л >. >..

д > < > X r. .1 > < > X > -t Ч i Ф 4 t> 4

-+hf RecipelD PK

I RecipeTitle

RecipeClassID PK

Pre pa ration I Nores


H-

ij 11 .iKinit ti !<.> i.> > i ф!и м ;4*; i.M4i > i*> i К1>* 1 ♦ *Ш*и >t<w i4- K*iV *

Recipe Classes

V , V . r ; > v Ч- r f - r f r

J RecipeClassID PK

\ RecipeClassDescription

vj .


Рис. 9.7.

Таблицы из примера базы данных Recipes, необходимые для извлечения всей информации о рецептах

еще не определено ни одного рецепта, и все детали рецептов и их компонентов. На рис. 9.7 представлены все таблицы, необходимые для ответа на данный запрос.

Похоже, что нужны данные из пяти различных таблиц. Их можно получить путем построения более сложного условия FROM, вкладывая условия JOIN в условия JOIN. Фокус вот в чем: везде, где можно определить имя таблицы, можно также определить взятое в целом условие JOIN, заключенное в скобки. На рис. 9.8 представлен упрощенный вариант соединения двух таблиц (для образования простого

также

с корреляционными именами).

iiiiiiiilii

l-DIStlNCT

:>::-i:;;.j.-


имятаблицы

Типтироваиное выражение



LEFT

RIGHT


JOIN имятоблицы

OUTER

ON Условие поиска

Рис. 9.8. Простая операция JOIN двух таблиц

Для того чтобы добавить третью таблицу к этому соединению, просто поставьте открывающую скобку перед именем первой таблицы, добавьте закрывающую скобку после условия поиска, а затем добавьте еще одно JOIN, имя таблицы, ключевое слово ON и еще одно условие поиска. На рис. 9.9 показано, как это сделать.



1 ... 85 86 87 [ 88 ] 89 90 91 ... 152

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика