Эквивалентность оператора JOIN в книге отображается неверно? - PullRequest
0 голосов
/ 07 мая 2020

Сразу после рисунка 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 для тех классов рецептов, которые не имеют подходящих рецептов, поэтому кажется, что будет правильным решением, если мы сделаем предположение, что база данных является полной, чтобы мы не потеряли некоторые рецепты по пути с использованием внутренних соединений.

Что я не понимаю в том, как работают объединения? Я не понимаю, насколько они эквивалентны.

Изменить - отформатированы запросы для облегчения чтения.

1 Ответ

0 голосов
/ 07 мая 2020

Запросы эквивалентны, но не по указанной причине. Условие:

ON Recipes.RecipeID = Recipe_Ingredients.RecipeID

превращает первый запрос в последовательность INNER JOIN s.

Условие:

ON Ingredients.IngredientID = Recipe_Ingredients.IngredientID

превращает второй запрос в серию of INNER JOIN s.

Когда все соединения равны INNER JOIN s, порядок не имеет значения.

Формат запроса ужасен - автор не использует псевдонимы таблиц. Имея опыт в этой области, я знаю, что мне пришлось немало потрудиться, чтобы запросы хорошо «печатались» в книгах, и удаление длинных псевдонимов таблиц определенно помогает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...