Сразу после рисунка 9-9 (в главе 9) SQL Queries for Mere Mortals 4-е издание, следующие два запроса представлены как эквивалентные решения, но они явно не эквивалентны.
Постановка задачи:
“I need all the recipe types, and then the matching recipe names, preparation instructions,
ingredient names, ingredient step numbers, ingredient quantities, and ingredient measurements
from my recipes database, sorted in recipe title and step number sequence.”
Запрос 1:
SELECT
Recipe_Classes.RecipeClassDescription,
Recipes.RecipeTitle,
Recipes.Preparation,
Ingredients.IngredientName,
Recipe_Ingredients.RecipeSeqNo, Recipe_Ingredients.Amount,
Measurements.MeasurementDescription
FROM
(
(
(
Recipe_Classes
LEFT OUTER JOIN Recipes
ON Recipe_Classes.RecipeClassID = Recipes.RecipeClassID
)
INNER JOIN Recipe_Ingredients
ON Recipes.RecipeID = Recipe_Ingredients.RecipeID
)
INNER JOIN Ingredients
ON Ingredients.IngredientID = Recipe_Ingredients.IngredientID
)
INNER JOIN Measurements
ON Measurements.MeasureAmountID = Recipe_Ingredients.MeasureAmountID
ORDER BY RecipeTitle, RecipeSeqNo
Запрос 2:
SELECT
Recipe_Classes.RecipeClassDescription,
Recipes.RecipeTitle, Recipes.Preparation,
Ingredients.IngredientName,
Recipe_Ingredients.RecipeSeqNo,
Recipe_Ingredients.Amount,
Measurements.MeasurementDescription
FROM
Recipe_Classes
LEFT OUTER JOIN
(
(
(
Recipes INNER JOIN Recipe_Ingredients
ON Recipes.RecipeID = Recipe_Ingredients.RecipeID
)
INNER JOIN Ingredients
ON Ingredients.IngredientID = Recipe_Ingredients.IngredientID
)
INNER JOIN Measurements
ON Measurements.MeasureAmountID = Recipe_Ingredients.MeasureAmountID
)
ON Recipe_Classes.RecipeClassID = Recipes.RecipeClassID
ORDER BY RecipeTitle, RecipeSeqNo
После запроса 1 автор кажется, что Query 2 эквивалентен ему, поскольку он пишет:
Joining more than two tables in an alternate sequence
To solve the request I just showed you using five tables, I could have also stated the SQL as follows:
Query 1 и Query 2 выглядят неэквивалентными. Если у вас есть типы рецептов без рецептов (что в книге указано как часть проблемы), запрос 1 не вернет их, поскольку INNER JOINs анализируются после LEFT OUTER JOIN, уничтожая эти строки.
Следовательно, запрос 1 неверен.
Запрос 2 фактически вернет все классы рецептов со значениями столбца NULL для тех классов рецептов, которые не имеют подходящих рецептов, поэтому кажется, что будет правильным решением, если мы сделаем предположение, что база данных является полной, чтобы мы не потеряли некоторые рецепты по пути с использованием внутренних соединений.
Что я не понимаю в том, как работают объединения? Я не понимаю, насколько они эквивалентны.
Изменить - отформатированы запросы для облегчения чтения.