|
Программирование >> Исключение дубликатов строк
На самом деле стандарт SQL интерпретирует SOME и ANY как одно и то же. Поэтому, если указать < > SOME или < > ANY, этот предикат будет True, если типизированное выражение слева не равно по крайней мере одному из значений в списке. Другим смущающим моментом является то, что если подзапрос не возвращает строк, то любой предикат сравнения с ключевым словом ALL является True и любой предикат сравнения с ключевыми словами SOME или ANY является False. Внимание! Стандарт SQL определяет концепцию конструктора строкового значения. Если ваша база данных поддерживает эту часть стандарта, то выражение SELECT в количественном предикате может возвратить более одного столбца. В этом случае элемент в левой части сравнения должен представлять список типизированных выражений, разделенный запятыми и заключенный в скобки. Также выражение SELECT должно возвратить несколько столбцов, разных по количеству числу типизированных выражений слева. Например, можно построить оператор SQL, подобный следуюшему: SELECT * FROM МуТаЫе WHERE (MyTable.ColumnI, MyTable.Column2) > ALL (SELECT ColumnA. ColumnB FROM OtherTable) Проверьте no документации для базы данных, поддерживает ли она этот синтаксис. Рассмотрим пару запросов, чтобы увидеть использование кoличectвeнныx предикатов. Вначале решим задачу в базе данных Recipes. Обратитесь к рис. 11.8, на котором представлены нужные нам таблицы. Show те the recipes that have beef or garlic . ( Показать рецепты, содержащие говядину и чеснок*.) Преобразование: Select recipe title from the recipes table where recipe ID is in the selection of recipe IDs from the recipe ingredients table where ingredient ID equals any of the selection of ingredient IDs from the ingredients table where ingredient name is beef or garlic (Выбрать заголовок рецепта из таблицы Рецепты , где идентификатор рецепта находится в выборке идентификаторов рецептов из таблицы Компоненты рецептов , где идентификатор компонента равен любой выборке идентификаторов компонента из таблицы Компоненты , где название компонента beef или garlic Уточнение Select recipe title from the recipes tebte where recipe ID in the (selectwi-of recipe 1Ш from the recipe ingredients table where ingredient ID equala = any of the (selecttofi-ef ingredient ID from the ingredients table where ingredient name Ь beef tft garlic )) (Выбрать заголовок рецепта из Рецепты , где идентификатор рецепта в (Выбрать идентификатор рецепта из Компоненты рецептов , где идентификатор компонента = любой (Выбрать идентификатор компонента из Компоненты , где название компонента - beef , garlic )) SELECT Recipes.RecipeTitle FROM Recipes WHERE Recipes.RecipelD IN (SELECT RecipeIrrgretJlents. RecipelD FROM Recipe.Ingredients WHERE Recipe.Ingredients.IngredientID = ANY (SELECT Ingredients.IngredientID FROM Ingredients WHERE Ing redients.Ing redientName IN (*Beef, Garlic*))) .... CATEGORres CategorylD PK CategoryDescription He возникло ли у вас ощущения, что можно также использовать IN вместо = ANY? Если возникло, то вы правы! Можно также создать JOIN между Recipe Ingredients и Ingredients в первом подзапросе, чтобы возвратить нужный список идентификаторов рецептов RecipelD. В SQL всегда существует более одного способа решения конкретной задачи. Иногда использование количественного предиката может сделать запрос более понятным. Теперь решим немного более сложную задачу, чтобы показать реальную мощность количественных предикатов. В этом примере используется учебная база данных Sales Order (Заказы на закупку). На рис. 11.10 представлены используемые для этого таблицы. PRpptiCTS ProductNumber PK ProductName ProductDescriptioii ReiatlPrjce QuantilyOnHarKi CategorylD FK Рис. 11.10. Таблица Categories и связанная с ней таблица Products Find all accessories that are priced greater than any clothing item . ( Найти все аксессуары, цена которых выше, чем любой единицы одежды .) Преобразование: Select product name and retail price from the products table joined with the categories table on category ID where category description is accessories and retail price is greater than all of the selection of retail price from the products table joined with the categories table on category ID where category name is clothing (Выбрать наименование товара и розничную цену из таблицы Товары , соединенной с таблицей Категории по идентификатору категории, где описание категории - аксессуары , а розничная цена больше, чем любая из выборки розничной цены из таблицы Товары , соединенной с таблицей Категории по идентификатору категории, где наименование категории - одежда ) Уточнение: Select product name а ё retail price from the products table joined with the categories table on category ID where category description ts = accessories and retail price is greater than > all of the (selection of retail price from the products table joined with the categories table on category ID where category name ts = clothing ) (Выбрать наименование товара, розничную цену из Товары , соединенной с Категории по идентификатору категории, где описание категории = аксессуары и розничная цена > любой (Выбрать розничную цену из Товары , соединенной с Категории по идентификатору категории, где наименование категории = одежда )) SQL SELECT Products.ProductName, Products.RetailPrice FROM Products INNER JOIN Categories ON Products.CategorylD = Categories.CategorylD WHERE Categories.CategoryDescription = Accessories AND Products.RetailPrice > ALL (SELECT Products.RetailPrice FROM Products INNER JOIN Categories ON Products.CategorylD = Categories.CategorylD WHERE Categories.CategoryDescription = Clothing) Что здесь происходит? Подзапрос извлекает все цены д/1я единиц одежды. Затем внешний запрос выведет список всех аксессуаров, цена которых больше, чем цена единицы одежды из подзапроса.
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |