|
Программирование >> Исключение дубликатов строк
WHERE Ing redlent.Classes.Ing redlentClassDesc ription = Seafood) Ha рис. 11.8 можно увидеть, что в таблице Recipe Ingredients может быть несколько строк для каждой строки в таблице Recipes. Набор результатов, определенный условием FROM, будет содержать по крайней мере столько строк, сколько строк в Recipe Ingredients, со значением столбца RecipeTitle, повторенным много раз. Даже когда добавляется фильтр для ограничения результата компонентами в классе Seafood, все еще будет получено более одной строки на рецепты в любом рецепте, который содержит более одного компонента морепродуктов. Использование этой методики подзапроса действительно важно, когда требуется составить список более чем из одних заголовков рецептов. Предположим, что нужен также список всех компонентов из каждого рецепта, содержащего компонент морепродуктов. Если воспользоваться сложным соединением во внешнем запросе и отфильтровать класс компонентов Seafood, как это было сделано выше, то мы получим только компоненты морепродуктов, но не получим всех остальных компонентов рецепта. Зададим один дополнительный и немного более сложный запрос: List all ту recipes and all ingredients for recipes that have a Seafood ingredient . ( Привести список всех рецептов и всех компонентов для рецептов, содеротщих компонент морепродуктов Преобразование: Select recipe title and ingredient name from the recipes table joined with the recipe ingredients table on recipe ID, and then joined with the ingredients table on ingredient ID where the recipe ID is in the selection of recipe IDs from the recipe ingredients table joined with the ingredients table on ingredient ID, and then joined with the ingredient classes table on ingredient class ID where ingredient class description is seafood (Выбрать заголовок рецепта и название компонента из таблицы Рецепты , соединенной с таблицей recipeingredients по идентификатору рецепта, а затем соединенной с таблицей Компоненты по идентификатору компонента, где идентификатор рецепта находится в выборке идентификаторов рецептов из таблицы recipe ingredients, соединенной с таблицей Компоненты по идентификатору компонента, а затем соединенной с таблицей ingredient classes по идентификатору вида компонента, где описание вида компонента - морепродукты ) Уточнение: Select recipe title, ш6 ingredient name from ttte recipes table joined with the recipe ingredients table on recipe ID, and then joined with the ingredients table on ingredient ID where the recipe ID in the (selectton-of recipe IDs from the recipe ingredients table joined with the ingredients table on ingredient ID, and then joined with the ingredient classes table on ingredient class ID where ingredient class description ts = seafood ) (Выбрать заголовок рецепта, название компонента из Рецепты , соединенной с recipe ingredients по идентификатору рецепта, соединенной с Компоненты по идентификатору компонента, где идентификатор рецепта в (Выбрать идентификаторы рецепта из recipe ingredients, соединенной с Компоненты по идентификатору компонента, соединенной с ingredient classes по идентификатору вида компонента, где описание вида компонента = морепродукты )) SQL SELECT Recipes.RecipeTitle, Ingredients.IngredientName FROM (Recipes INNER JOIN Recipe.Ingredients ON Recipes.RecipelD = Recipe Ingredients.RecipelD) INNER JOIN Ingredients ON Ingredients.IngredientlD = RecipeIngredients.IngredientlD WHERE Recipes.RecipelD IN (SELECT RecipelD FROM (RecipeIngredients INNER JOIN Ingredients ON RecipeIngredients.IngredientlD = Ingredients.IngredientlD) INNER JOIN Ingredient Classes ON Ingredients.IngredientClassID = Ing redient.Classes.Ing redientClassID WHERE IngredientClasses.IngredientCiassDescription = Seafood) Основной момент здесь состоит в том, что сложное внешнее соединение в основной части запроса извлекает все компоненты выбранных рецептов, а сложный подзапрос возвраш,ает список идентификаторов рецепта только для рецептов с морепродуктами. Это выглядит так, будто мы дважды выполняем сложное соединение, но именно в этом безрассудстве и состоит метод. Определят количество - nU/SOMC/RNV Предикат IN позволяет сравнивать столбец или выражение со списком, чтобы определить, содержится ли этот столбец или выражение в списке (IN). Другими словами, столбец или выражение рано одному из элементов списка. Если нужно установить, является ли столбец или выражение больше или меньше, чем любое, все или некоторые из элементов в списке, то можно использовать количественный предикат. На рис. 11.9 представлен синтаксис. Оператор $ШСТ О- SELECT -т г-......- Титтрошанное выражение псевдоним iWiiiJilifiHMi! tiiiiiiiiiii>-ri;i ;i>iiii>iii f :ihiyi-ijLM.! 4>.i!i>: 4*: hi8:#i>ii:!iijt8Tiii:rjii ji!i)i FROM Ссылка HO юблицу :S:.:-::: J:..:::-;,:;;;Y: WHERE Гипизировашое шрожфние Mt. --- (Выраженив SELECT) - SOME ANY - Рис. 11.9. Использование количественного предиката в операторе SELECT В данном случае выражение SELECT должно быть табличным подзапросом, который возвращает только один столбец и ни одной или несколько строк. Когда подзапрос возвращает больше одной строки, значения в строках составляют список. Как можно видеть, этот предикат объединяет оператор сравнения с ключевым словом, которое указывает системе базы данных, как этот оператор применяется к элементам списка. При использовании ключевого слова ALL результат сравнения должен иметь значение True для всех значений, возвращенных подзапросом. При использовании ключевого слова SOME или ANY результат сравнения должен быть True хотя бы для одного значения в списке. Когда подзапрос возвращает несколько строк, запрос для = ALL всегда будет False, если только все значения, возвращенные подзапросом, не являются одинаковыми и типизированное выражение в левой части сравнения равно каждому из них. Согласно этой же логике можно подумать, что < > ANY всегда будет False, если типизированное выражение в левой части всегда равно любому значению в списке.
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |