Доступ к SQL с помощью TOP 5, возвращающих более 5 результатов? - PullRequest
9 голосов
/ 20 мая 2009

Я использую следующее утверждение

SELECT TOP 5 rootcause, COUNT(IIF(accountability="Team 1",1,0))
FROM  MOAQ
WHERE CDT=1
GROUP BY rootcause

MOAQ - это еще один запрос, который возвращает около 20 полей из 4 таблиц, ничего особенного. Это работает, как ожидалось, и я получаю 5 результатов.

Если я добавлю предложение ORDER BY в условное поле, я получу 8 результатов. Если я сортирую по первому полю, проблем не будет.

Кто-нибудь знает, что может происходить?

Изменить, чтобы уточнить - На данный момент я тестирую только из Access 2003, возможный оператор будет параметризованным запросом через ADO из интерфейса Excel.

Ответы [ 2 ]

30 голосов
/ 20 мая 2009

Это известный эффект директивы top в Access, но он не очень хорошо известен ...

Директива top не возвращает верхние n элементы, как можно легко поверить. Вместо этого он возвращает не менее n отдельных элементов, определяемых по порядку результата.

В большинстве случаев это то же самое, но в вашем примере, где элементы с 5 по 8 имеют одинаковое значение заказа, все они включены. Возвращает первые пять элементов, а затем и все элементы, имеющие такое же значение заказа, что и пятый элемент.

Если вы не применяете порядок к таблице, учитываются все поля, поэтому, если у вас есть уникальное поле в результате, запрос всегда вернет пять элементов. То же самое, конечно, если уникальное поле включено в порядок.

Другие диалекты SQL могут вести себя по-разному. Например, одна только директива top в T-SQL (SQL Server) никогда не возвращает больше, чем n элементов. Однако, указав пункты with ties и order by вместе с top, можно наблюдать то же поведение, что и в Access.

1 голос
/ 09 июля 2009

Перейдите на страницу в именах справки Access 2003 О режиме запросов ANSI SQL (MDB) , затем разверните «Зачем использовать ANSI-92 SQL?» тема, и вы увидите это:

"Использование предложения LIMIT TO nn ROWS для ограничения количества строк, возвращаемых запросом"

Поэтому просто переведите пользовательский интерфейс Access в режим запросов ANSI-92 или используйте в коде OLE DB (например, ADO) и добавьте предложение

LIMIT TO 5 ROWS

к вашему запросу.

...

Только шучу! Это просто еще один пример того, как ядро ​​базы данных Access плохо документировано. Я думаю, что кто-то из команды документации Access сделал не слишком необоснованное предположение о том, что так называемый режим запросов ANSI-92 ядра базы данных Access будет соответствовать стандарту ISO / ANSI SQL-92. Это не так.

Ядро базы данных Access имеет собственный проприетарный (т. Е. Не SQL-92 Standard) синтаксис TOP n (не путать с собственным проприетарным синтаксисом TOP n SQL Server, который семантически отличается). В двух словах, он не разрешает дубликаты. Если критерии удовлетворяют каждой строке таблицы, вы получите каждую строку таблицы в наборе результатов.

Обходной путь - использовать курсор для чтения только первых n строк в наборе результатов. Поскольку SQL базы данных Access не поддерживает процедурный код или явные курсоры, вам придется делать это на стороне клиента, например откройте объект Recordset и прочитайте первые n записей в сфабрикованном наборе записей ADO.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...