MS Access 转 SQL 查询问题

4
我有一个查询语句,原本应该在 MS Access 中使用,但是数据库是 SQL 数据库。当我在 SQL 环境中运行此查询时,它能够完美运行,但是在 MS Access 中运行时出现错误。我对 SQL 的了解很少(来自于 MySQL),对 MS Access 更不了解。
这个查询语句的目的是给出某一类竞拍者在单个拍卖会上投标的总人数(无论是否成功),该类竞拍者赢得的物品的总价值以及该竞拍者类型。以下是查询语句:
SELECT     Total.count, SUM(dbo_tblItem.item_premium + dbo_tblItem.item_pr) AS SumTotal, dbo_tblBidder.bidder_type
FROM         dbo_tblBidder LEFT OUTER JOIN
                  dbo_tblItem ON dbo_tblItem.item_bidder_number = dbo_tblBidder.bidder_number   AND 
                  dbo_tblItem.item_sale_id = dbo_tblBidder.bidder_sale_id LEFT OUTER JOIN
                      (SELECT     COUNT(bidder_type) AS count, bidder_type
                        FROM          dbo_tblBidder AS tblBidder_1
                        WHERE      (bidder_sale_id = 235)
                        GROUP BY bidder_type) AS Total ON dbo_tblBidder.bidder_type = Total.bidder_type
WHERE     (dbo_tblBidder.bidder_sale_id = 235)
GROUP BY dbo_tblBidder.bidder_type, Total.count
ORDER BY dbo_tblBidder.bidder_type

MS Access告诉我:

查询表达式中的语法错误(缺少运算符)"。

然后,它在以下内容中突出显示了“dbo_tblBidder.bidder_number”中的“mber”:

dbo_tblItem ON dbo_tblItem.item_bidder_number = dbo_tblBidder.bidder_number

我不知道高亮显示是否实际上是任何内容的一部分。

3个回答

5
当您连接超过2个表时,Access需要括号,并且对其位置非常挑剔。(尽管您查询的数据源之一是子查询而不是实际表格,但在连接和括号方面,它被视为与表格相同。)建议您在Access的查询设计器中将其构建为新查询,以查看它如何为连接的表放置括号。
“count”是保留字,因此我在查询中出现该名称的每个地方都加了括号,以减少混淆数据库引擎的机会。
对于Access的db引擎,请使用LEFT JOIN而不是LEFT OUTER JOIN。
我认为这可能接近您所需的内容。
SELECT
    Total.[count],
    SUM(dbo_tblItem.item_premium + dbo_tblItem.item_pr) AS SumTotal,
    dbo_tblBidder.bidder_type
FROM         
    (dbo_tblBidder LEFT JOIN dbo_tblItem
        ON (dbo_tblItem.item_bidder_number = dbo_tblBidder.bidder_number
           AND dbo_tblItem.item_sale_id = dbo_tblBidder.bidder_sale_id)
        )
    LEFT JOIN (
        SELECT     COUNT(bidder_type) AS [count], bidder_type
        FROM          dbo_tblBidder
        WHERE      bidder_sale_id = 235
        GROUP BY bidder_type
        ) AS Total
        ON dbo_tblBidder.bidder_type = Total.bidder_type
WHERE     dbo_tblBidder.bidder_sale_id = 235
GROUP BY dbo_tblBidder.bidder_type, Total.[count]
ORDER BY dbo_tblBidder.bidder_type;

哇,太厉害了!你是我的新英雄~非常感谢你。 - James
"你的查询数据源之一是一个子查询,而不是实际表格" - 这就是SQL标准所称的“派生表”,并进一步说明,“一个表格可以是基础表、视图表或者派生表。” - onedaywhen
1
但是使用Access的查询设计器的反面是,生成的SQL代码通常冗长且((充满) ((无意义的) ((方括号和圆括号)))), 使得对人类来说更难阅读。 - onedaywhen
@onedaywhen 对的。如果一个人无法容忍这些多余的方括号和圆括号,他会憎恶查询设计器的。我已经安心了。 :-) - HansUp

0

尝试在您的ON子句周围加上括号,例如:

left outer join dbo_tblItem on (dbo_tblItem.item_bidder_number = dbo_tblBidder.bidder_number
    and dbo_tblItem.item_sale_id = dbo_tblBidder.bidder_sale_id)

我已经尝试过了,但是它仍然显示相同的错误,只不过现在是带有“dbo_tblItem.item_bidder_number = dbo_tblBidder.bidder_number AND dbo_tblItem.item_sale_id = dbo_tblBidder.bidder_sale_id LEFT OUTER JOIN (SELECT COUNT(bidder_type) AS count, bidder_type”而不是空引号。 - James

0

你的问题听起来像是在Access中链接了SQL Server表。
你是想通过代码执行查询还是在Access查询设计器中执行?

无论你如何执行查询,都可以直接将其发送到SQL Server,绕过Access。

这样做的好处是你可以使用SQL Server的SQL方言,我认为它比Access的SQL方言更强大。
此外,根据我的经验,SQL Server比Access更快。

如果你正在使用查询设计器:

你可以在查询设计器中创建一个经过传递的查询:
如何在Access中创建SQL经过传递查询

如果你想通过代码执行查询:
下面是一个示例函数,它将直接向SQL Server发送查询并返回一个记录集:

Public Function OpenRecordset(ByVal SQL As String) As DAO.Recordset    
    Dim QD As QueryDef
    Set QD = CurrentDb.CreateQueryDef("")
    With QD
        .Connect = "Your connection string to the SQL Server database"
        .ReturnsRecords = True
        .SQL = SQL
        Set OpenRecordset= QD.OpenRecordset
        QD.Close
    End With
    Set QD = Nothing    
End Function

使用示例:

Public Function Test()    
    Dim RS As DAO.Recordset        
    Set RS = OpenRecordset("select getdate()")        
    MsgBox RS.Fields(0)        
    RS.Close
    Set RS = Nothing    
End Function

使用 SQL Server 函数 getdate() 将返回当前日期和时间。


我想看看James的查询如何从SQL Server的SQL方言的额外能力中受益。我对此一无所知。 - HansUp
@HansUp:什么是“drawing a blank on that one”的意思?(英语不是我的母语) - Christian Specht
抱歉!“Drawing a blank”意味着我无法确定任何好处。另一个类似的美国习语是“一无所获”。(这可能也没有帮助!)在某件事上不成功。 - HansUp
好的,我明白 :-) 当然,SQL Server与Access的性能可能取决于数据库大小、查询复杂度等因素。我只能谈谈我的经验:在工作中,我们在Access 2003上运行整个ERP系统,使用SQL Server 2005后端(>80 GB数据库大小)。在这种情况下,如果我们直接在SQL Server上运行查询(基本上与上面相同的“OpenRecordset”函数),那么复杂查询(特别是连接查询)会快得多,而不是在Access中查询链接的SQL Server表。 - Christian Specht
这对我也很有趣,Christian。我不知道ODBC会将多少处理负载交给SQL Server而不将其提交为透传查询。如果James尝试两种方式并告诉我们影响将会很好。但是我的第一个评论是关于如何使用SQL Server的SQL语言优化此查询的部分。那就是我看不到的部分… 我“什么也没想到”。 - HansUp

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接