|
Программирование >> Исключение дубликатов строк
WHERE Engagements.ContractPrice > ALL (Select SUM(ContractPrice) FROM Engagements *AS E2 WHERE E2.CustomerlD <> Customers.CustomerlD GROUP BY E2.CustomerlD) Проанализируем то, что выполняется в подзапросе. Для кавдого ангажемента, который рассматривается запросом в JOIN клиентов и ангажементов, подзапрос вычисляет SUM всех цен контрактов для всех других клиентов и объединяет их в группы по идентификатору клиента. Поскольку в базе данных имеется несколько клиентов, подзапрос возвращает несколько значений SUM - по одному для каждого из других клиентов. По этой причине нельзя использовать условие сравнения просто на больше (>). Однако можно воспользоваться количественным условием сравнения больше, чем все (> ALL) для проверки множества значений. Если выполнить этот запрос для примера базы данных Entertainment Agency (сохраненного как Biggest Big Contract ), то обнаружится, что только один контракт удовлетворяет всем требованиям.
Моделирование оператора SCLCCT DISTINCT Можно ли использовать условие GROUP BY, не включая каких-либо агрегатных функций в условие SELECT? Конечно можно! При этом будет получен тот же эффект, что и при использовании ключевого слова DISTINCT (см. главу 4). Рассмотрим простой запрос, требующий уникальных значений, и разрешим его, используя оба метода: Show те the unique city names from the customers table . ( Показать уникальные названия городов из таблицы Клиенты .) Преобразование 1: Select the distinct city names from the customers table (Выбрать неповторяющиеся названия городов Уточнение: из таблицы Клиенты ) Select the distinct city names from the customers table (Выбрать неповторяющиеся названия городов из Клиенты ) SELECT DISTINCT Customers.CustCityName FROM Customers Преобразование 2/ Select city name from the customers table, grouped by Уточнение: city name (Выбрать названия городов из таблицы Клиенты , сгруппированные по названию города) SQL SELECT Customers.CustCityName FROM Customers GROUP BY Customers.CustCityName GROUP BY объединяет в группу все строки по определенному вами столбцу пирования и возвращает одну строку для каждой группы. Это немного другой способ получения того же результата, который был получен с ключевым словом DISTINCT. Какой из них лучше? Нам кажется, что DISTINCT более понятное утверждение того, что нужно, но ваша СУБД может решить задачу быстрее при использовании GROUP BY. Наложение некоторых ограничений Добавление условия GROUP BY налагает определенные ограничения на построение запроса. Рассмотрим эти ограничения, чтобы оградить вас от попадания в обычные ловушки. Огрониченип но использононие столбцов Когда добавляется условие GROUP BY, это означает, что от системы базы данных запрашивается формирование уникальных групп строк из строк, возвраиденных таблицами, определенными в условии FROM и отфильтрованными условием WHERE. В условии SELECT можно использовать столько составных выражений, сколько требуется, и эти выражения могут использовать любые столбцы таблицы, определенной условиями FROM и WHERE. Ссылка на столбец в составном выражении, а также включение этого столбца в спецификацию группирования, вероятно, не имеет смысла. Если выбрать включение выражений со ссылкой на столбцы, но без агрегатной функции, то потребуется перечислить в списке все столбцы, которые используются таким образом, в условии GROUP BY. Одна из наиболее обычных ошибок состоит в предположении, что, если столбцы исходят из уникальных строк, то в выражениях, которые не являются составными, могут быть ссылки на эти столбцы. Рассмотрим, например, некорректный запрос, который включает значение первичного ключа, т. е. то, что по определению является уникальным. Display the customer ID, customer full name, and the total of all engagement contract prices , ( Вывести на экран идентификатор клиента, полное имя клиента и общую сумму всех цен контрактов ангаоюемента .) Преобразование: Select customerID, customer first name, and customer last name as customer full name, and the sum of contract prices from the customer table joined with the engagements table on customer ID, grouped by customer ID (Выбрать идентификатор клиента, имя клиента и фамилию клиента как полное имя клиента, и сумму цен контрактов из таблицы Клиенты , соединенной с таблицей Ангажементы по идентификатору клиента, сгруппированные по идентификатору клиента) Уточнение: customer Select customer ID, customer first name, afte last name as customer full name, and the sum of (contract price)s from the customer table joined with the engagements table on customer ID, grouped by customer ID (Выбрать идентификатор клиента, имя клиента фамилию клиента как полное имя клиента, sum (цена контракта) из Клиенты , соединенной с Ангажементы по идентификатору клиента, сгруппированные по идентификатору клиента) SELECT Customers.CustomerlD, Custome rs.CustFlrstName Customers.CustLastName AS CustFullName, SUM(Engagements.ContractPrice) AS TotalPrice FROM Customers INNER JOIN Engagements ON Customers.CustomerlD = Engagements.CustomerlD GROUP BY Customers.CustomerlD Нам известно, что CustomerlD (идентификатор клиента) является уникальным Д/1Я клиента. Группирования по CustomerlD должно быть достаточно для извлечения уникальной информации об имени и фамилии клиента в пределах групп, сформированных по CustomerlD. Однако SQL - это язык, основанный на синтаксисе, а не на семантике. Иначе говоря, SQL не принимает во внимание любую информацию, которая может подразумеваться структурой таблиц БД, включая и то, какие столбцы являются первичным ключом. SQL требует синтаксической чистоты запроса и возможности его преобразования без учета какой-либо информации о структуре таблиц, лежащих в его основе. Таким образом, показанный выше оператор SQL приведет к ошибке в системе базы данных, что полностью соответствует стандарту SQL, потому что в условие SELECT включены столбцы, которые отсутствуют в агрегатной функции, а также и в условии GROUP BY (CustFirstName и CustLastName). Правильный SQL-запрос выглядит следующим образом: SELECT Customers. CustomerlD, Custome rs.CustFi rstName
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки. |