MS-Access DISTINCTROW больше не работает, если связанные таблицы хранятся на SQL2008-сервере - PullRequest
0 голосов
/ 06 марта 2011

У меня есть запрос в MS-Access, как это:

select DISTINCTROW companies.* from companies, contacts, companies left join contacts on contacts.com_uid = companies.com_uid (This is the ms-access form of a standard "left-join")

[Компании] и [контакты] являются связанными представлениями на SQL Server 2008, драйвер ODBC - «собственный клиент SQL Server 10.0». Оба представления выглядят как «выберите * из [компании], где удалено = 0» и «выберите * из [контактов], где удаление = 0»

Результат неверный, так как компании показывают столько контактов.

Если представления хранятся в SQL2000 и связаны с ODBC-драйвером «SQL Server», все в порядке: все компании отображаются ровно один раз.

Есть ли какие-либо решения, чтобы снова получить результат с помощью DISTINCTROW?

Ответы [ 3 ]

0 голосов
/ 06 марта 2011

Давайте перестанем говорить о синтаксисе левого соединения в ms-access. Дело в том, что если связанные таблицы являются представлениями на SQL Server 2000:

create view [companies] as
select * from [TabCompanies] where deleted  = 0

и

create view [contacts] as
select * from [TabContcts] where deleted = 0

Эти представления являются связанными с ODBC таблицами в базе данных ms-access 2003/2007. Вопросы отображаются в ms-access для запроса типа

select distinctrow [companies].* from [companies] left join [contacts] on [companies].com_uid = contacts.com_uid] where [contacts].[function] like 'C*'

(давайте забудем этот альтернативный синтаксис и посмотрим на результат, предполагая, что левое объединение работает без ошибки или синтаксической ошибки)

Этот DISTINCTROW является функцией ms-доступа и не известен в sql-сервере, и, на мой взгляд, результат такой же, как DISTINCT, но работает также, даже если есть столбцы с типом данных изображений, например.

Все вместе мы ожидаем того же самого, что и Кэтколл в своем ответе сказал: «выберите * из компаний», НО ЭТО НЕ, почему?

Это только отрывок из всего запроса, который может не иметь смысла для производства, но показывает, что изменилось поведение, к которому подключен sql2008.

0 голосов
/ 08 марта 2011

Цель DISTINCTROW - сделать редактируемые две стороны соединения N: 1.С декартовым произведением (from companies, contacts, companies) результат не может быть редактируемым, поэтому DISTINCTROW не имеет никакого преимущества перед DISTINCT.

Во-вторых, независимо от того, что вы говорите, невозможно иметь одну и ту же таблицу дважды вОТ предложения без псевдонима.Выложенный вами SQL не мог бы работать ни в одной версии Access.

Единственный способ, которым я могу представить, - в этом есть смысл, если вы опустите предложение WHERE.

РЕДАКТИРОВАТЬ НА ОСНОВЕ КОММЕНТАРИЙ:

Это должно работать:

  SELECT DISTINCT companies.*
  FROM companies INNER JOIN contacts ON companies.com_uid = contacts.com_uid
  WHERE contacts.function LIKE "C*"

Во-первых, я бы предположил нормальные отношения N: 1 между контактами и компаниями (то есть многие контактызаписи связаны с какой-либо отдельной записью компании), поэтому для обеих таблиц в предложении FROM необходим DISTINCT, чтобы возвращать по одной строке для каждой компании.

Во-вторых, если вы поместите критерии в таблицу наС другой стороны, нет смысла пытаться использовать LEFT JOIN, так как он не изменит возвращаемых записей (используйте LEFT JOIN, если вы хотите вернуть записи независимо от того, есть ли записи в таблице намного сторон присоединения).Таким образом, ВНУТРЕННЕЕ СОЕДИНЕНИЕ выполнит работу за вас и будет более эффективным (внешние СОЕДИНЕНИЯ просто медленнее, даже с критериями).

0 голосов
/ 06 марта 2011

Я удивлен, что он выполняет этот запрос вообще. Вы указываете таблицу «контакты» дважды.

Ваше LEFT JOIN должно возвращать каждую строку от "companies". Поскольку вы не извлекаете какие-либо столбцы из контактов, я уверен, что ваш запрос эквивалентен

SELECT * 
FROM companies

до тех пор, пока "компании" означает то, что он делает на обычном языке.

Если это не так, вы можете перенести нагрузку на SQL Server, либо создав представление в SQL Server, либо создав сквозной запрос в Access. Сквозной запрос должен быть написан на диалекте SQL вашего сервера (SQL Server 2008, диалект SQL).


Ваша редакция, воспроизведенная ниже, ничего не меняет в моих предыдущих комментариях.

select DISTINCTROW companies.* 
from companies, contacts, companies 
left join contacts on contacts.com_uid = companies.com_uid 
(This is the ms-access form of a standard "left-join")

Это , а не Форма доступа для левого соединения. Доступ не позволит этого:

from companies, contacts, companies 
left join contacts

, потому что теперь вы указываете обе таблицы дважды.

Исходя из ваших правок, я бы сказал, что запрос, который вы пытаетесь написать, по-прежнему эквивалентен

SELECT * 
FROM companies

Что вы получите, если запустите , что ?

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