我在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 native client 10.0“。这两个视图看起来都像"select * from companies deleted = 0“和"select * from contacts where delete = 0”。
结果是错误的,因为公司显示的联系人数量与公司的联系人数量一样多。
如果视图存储在SQL2000上并与ODBC驱动程序"SQL Server“链接,那么一切都很好:所有公司都只显示一次。
有没有什么解决方案可以让DISTINCTROW再次得到结果?
发布于 2011-03-07 00:56:07
让我们停止讨论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这些视图是ms-access 2003/2007MDB中的ODBC链接表。这些问题在ms-access中显示在如下查询上
select distinctrow [companies].* from [companies] left join [contacts] on [companies].com_uid = contacts.com_uid] where [contacts].[function] like 'C*'(让我们忽略替代语法,并假设left join工作时没有错误或语法错误)
这个DISTINCTROW是一个ms-access功能,在sql-server中是不知道的,在我看来,结果与DISTINCT一样,但即使有数据类型为image的列,也可以正常工作。
总而言之,我们希望到现在为止,就像Catcall在他的回答中说的“从公司中选择*”一样,但它不是,为什么?
这只是整个查询的摘录,对于生产可能没有任何意义,但它显示了连接sql2008时发生的行为变化。
发布于 2011-03-06 21:06:45
我很惊讶它竟然会执行这个查询。您指定了表"contacts“两次。
您的左连接应该返回"companies“中的每一行。由于您没有从contacts中检索任何列,因此我非常确定您的查询等同于
SELECT *
FROM companies只要“公司”指的是它在普通语言中的作用。
如果事实并非如此,您可以通过在SQL Server中创建视图或在Access中创建passthrough query来将负担交给SQL Server。直通查询必须使用服务器的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")这不是Access的左连接形式。Access不允许这样做:
from companies, contacts, companies
left join contacts因为现在两个表都指定了两次。
根据您的编辑,我会说您尝试编写的查询仍然等同于
SELECT *
FROM companies如果运行该命令,您会得到什么结果
发布于 2011-03-08 06:00:55
DISTINCTROW的目的是使N:1连接的两侧可编辑。对于笛卡尔积(from companies, contacts, companies),结果是不可编辑的,因此DISTINCTROW与DISTINCT相比没有优势。
其次,无论您说什么,在没有别名的FROM子句中不可能有两个相同的表。您发布的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来为每个公司返回一行。
其次,如果您将条件放在连接的多个端的表上,则没有理由尝试使用左连接,因为它不会更改返回的记录(当您想要返回记录时,不管表中连接的多个端上是否有记录,请使用左连接)。因此,内部连接将为您完成这项工作,并且效率更高(即使有条件,外部连接也会更慢)。
https://stackoverflow.com/questions/5210492
复制相似问题