Предикаты ALL, DISTINCT, DISTINCTROW, TOP
Указывают способ отбора записей в SQL запросе. Формат
SELECT [ALL | DISTINCT | DISTINCTROW | [TOP n [PERCENT]]] FROM table
Предикат | Описание |
ALL | По умолчанию. В результат запроса включаются все записи, удовлетворяющие условию. Следующие два запроса эквивалентны и выводят все записи из таблицы: SELECT ALL * FROM Employees ORDER BY EmployeeID; SELECT * FROM Employees ORDER BY EmployeeID; |
DISTINCT | Исключает из результата повторяющиеся данные в выбранных полях, оставляя в результате только уникальные значения. Например, запрос SELECT DISTINCT LastName FROM Employees; выведет каждую фамилию только один раз, даже если среди служащих есть однофамильцы, без DISTINCT такие фамилии будут выведены несколько раз. Если выбраны несколько полей, в результирующий набор включается только уникальная комбинация их значений. Результат запроса, содержащего DISTINCT, является не обновляемым,т.к. нет взаимно-однозначного соответствия результата запроса с исходным набором. Порядок выполнения операций: из источника выбираются указанные поля (формируются записи), из сформированных записей выбираются только уникальные. |
DISTINCTROW | Игнорирует совпадающие записи в исходном наборе независимо от выбранных в запросе полей. Пусть, например, таблицы Customers и Orders объединяются по полю CustomerID. В таблице Customers нет повторяющихся значений CustomerID, а в Orders есть, т.к. один заказчик может сделать несколько заказов. Следующий запрос выводит список заказчиков, сделавших хотя бы один заказ, без сведений о заказах SELECT DISTINCTROW CompanyName FROM Customers INNER JOIN Orders ON Customers.CustomerID = Orders.CustomerID ORDER BY CompanyName; Без этот запрос вывел бы заказчиков, сделавших более одного заказа, несколько раз. DISTINCTROW действует, если выводятся поля из нескольких, но не всех таблиц, участвующих в запросе. Если в запросе участвует только одна таблица или выводятся поля из всех таблиц, DISTINCTROW игнорируется. Порядок выполнения операций: из источника выбираются только уникальные записи, из них выбираются указанные поля (формируются записи запроса). |
TOP n [PERCENT] | Ограничивает вывод указанным числом (n) или указанной долей (n PERCENT) первых записей. Например, следующий запрос выведет имена 25 лучших студентов выпуска 1994 года SELECT TOP 25 FirstName, LastName FROM Students WHERE GraduationYear = 1994 ORDER BY GradePointAverage DESC; Без выражения ORDER BY будут выведены произвольные 25 записей, удовлетворяющие условию WHERE. TOP не различает одинаковые величины – если в предыдущем примере 25-й и 26-й студенты имеют одинаковую оценку, будут выведены 26 записей. Следующий запрос выведет первые 10% худших от общего числа студентов: SELECT TOP 10 PERCENT FirstName, LastName FROM Students WHERE GraduationYear = 1994 ORDER BY GradePointAverage ASC; Число n должно быть целым без знака, действие TOP не зависит от того, является ли запрос обновляемым. |
Использование DISTINCT эквивалентно установке свойства UniqueValues в Yes в окне конструктора запросов, а DISTINCTROW эквивалентно установке в Yes свойства UniqueRecords. Предикат TOP эквивалентен установке свойства TopValues в конструкторе или Top Values на панели Query Design. PERCENT соответствует % во введенной величине.
Пусть имеется таблица Clients
FirstName | ClientID |
Bob | |
Adam | |
Beverly | |
Bob |
и таблица Invoices
ClientID | InvoiceID |
Следующий запрос
SELECT ALL FirstName FROM Clients INNER JOIN Invoices
ON Clients.ClientID = Invoices.ClientID;
возвратит все записи объединения таблиц:
Result | Updatable |
Bob Bob Adam Adam Adam Bob Bob | Yes |
Запрос обновляемый.
Следующий запрос
SELECT DISTINCT FirstName FROM Clients INNER JOIN Invoices
ON Clients.ClientID = Invoices.ClientID;
возвратит только уникальные значения:
Result | Updatable |
Bob Adam | No |
Запрос необновляемый.
Следующий запрос
SELECT DISTINCTROW FirstName FROM Clients INNER JOIN Invoices
ON Clients.ClientID = Invoices.ClientID;
возвратит только уникальные значения полученного объединения:
Result | Updatable |
Bob Adam Bob | Yes |
Запрос обновляемый.
Следующий запрос
SELECT TOP 5 FirstName FROM Clients INNER JOIN Invoices
ON Clients.ClientID = Invoices.ClientID ORDER BY Invoices.InvoiceID;
возвратит первые 5 записей из объединения