«SELECT TOP», «LEFT OUTER JOIN», «ORDER BY» дает дополнительные строки - PullRequest
4 голосов
/ 09 марта 2010

У меня следующий Access 2002 запрос, который я выполняю через OLE DB в .NET:

SELECT  TOP 25 
        tblClient.ClientCode, 
        tblRegion.Region
FROM    (tblClient LEFT OUTER JOIN
            tblRegion ON tblClient.RegionCode = tblRegion.RegionCode)
ORDER BY tblRegion.Region

В tblClient имеется 431 запись, для которой RegionCode имеет значение NULL.
По какой-то причине вышеприведенный запрос возвращает все эти 431 запись вместо первых 25.

Если я изменю запрос на ORDER BY tblClient.Client (имя клиента) примерно так:

SELECT  TOP 25
        tblClient.ClientCode,
        tblRegion.Region
FROM    (tblClient LEFT OUTER JOIN
            tblRegion ON tblClient.RegionCode = tblRegion.RegionCode)
ORDER BY tblClient.Client

Я получаю ожидаемый набор результатов из 25 записей, показывающий смесь названий регионов и значений NULL.

Почему упорядочение по полю, полученному с помощью LEFT OUTER JOIN, не будет работать с предложением TOP?

РЕДАКТИРОВАТЬ: Возможное решение

Когда я также ORDER BY tblClient.Client запрос работает:

SELECT  TOP 25
        tblClient.ClientCode,
        tblRegion.Region
FROM    (tblClient LEFT OUTER JOIN
            tblRegion ON tblClient.RegionCode = tblRegion.RegionCode)
ORDER BY tblRegion.Region, tblClient.Client

Так как я не против, если я сортирую по второму полю, сейчас я сделаю это.

Ответы [ 4 ]

2 голосов
/ 09 марта 2010

Я видел это раньше, а потом это было потому, что Access вернул только 25 строк, если 25-й столбец, используемый в ORDER BY, был уникальным. Если это повторилось, Access также вернул связанные значения, что означает, что он может вернуть более 25 строк в одном ORDER BY и ровно 25 в другом.

Так что, если конец ORDER BY достигнет NULL, он покажет все связанные (NULL) значения. Эта ошибка, вероятно, исправлена ​​в более новых версиях Access, но поскольку у меня нет Access на этом компьютере, но вы можете попробовать:

выберите топ 5 {1,2,3,4,5,5,5,5} по возрастанию и по убыванию, чтобы проверить, применимо ли это к вашей версии Access.

НТН

2 голосов
/ 09 марта 2010

Поведение, которое вы видите, не потому, что поле извлекается через левое внешнее соединение, а потому, что поле имеет значение NULL

NULL в SQL не ведет себя как любое другое значение

Если a и b оба равны NULL, то a = b ложно. Таким образом, при сравнении для группирования доступа все значения NULL рассматриваются как разные значения

В этом случае, если вы хотите использовать TOP, вы можете исключить значения NULL, добавив

WHERE tblRegion.Region IS NOT NULL
1 голос
/ 09 марта 2010

У меня не установлен Access или ваша схема, но это работает?

SELECT  TOP 25 
        tblClient.ClientCode, 
        tblRegion.Region
FROM    (tblClient LEFT OUTER JOIN
            tblRegion ON tblClient.RegionCode = tblRegion.RegionCode)
ORDER BY NZ(tblRegion.Region,'')
0 голосов
/ 09 марта 2010

Когда я также ORDER BY tblClient.Client запрос, кажется, работает:

SELECT  TOP 25
        tblClient.ClientCode,
        tblRegion.Region
FROM    (tblClient LEFT OUTER JOIN
            tblRegion ON tblClient.RegionCode = tblRegion.RegionCode)
ORDER BY tblRegion.Region, tblClient.Client

Так как я не против, если я сортирую по второму полю, сейчас я сделаю это.

Я обновил вопрос, чтобы отразить это как возможное решение.

...