Предикаты 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 записей из объединения