[英]Excel VBA SQL Join Syntax Error
我正在写一个允许用户从列表框中选择客户的子程序。 选择记录为CustomerID(整数变量),并用于查询Access数据库文件。 然后,该子项应将有关指定客户的销售信息输出到excel工作表中,特别是:
访问文件具有我需要的3个表:客户,订单,订单项
我下面的代码应将客户ID与订单ID字段结合在一起,然后将其与订单ID结合在一起,并将订单ID与订单项结合起来。
' Define SQL statement to get order info for selected product.
SQL = "SELECT O.OrderDate, COUNT(O.OrderID), SUM(L.QuantityOrdered * L.QuotedPrice) AS [TotalCost] " _
& "FROM (((Customers C INNER JOIN Orders O ON C.CustomerID = O.CustomerID) " _
& "INNER JOIN ON O.OrderID = O.CustomerID) INNER JOIN LineItems L " _
& "ON O.OrderID = L.OrderID)" _
& "WHERE O.CustomerID =" & CustomerID & " " _
& "GROUP BY O.OrderDate, O.OrderID" _
& "ORDER BY O.OrderDate"
我不断收到“ FROM子句中的语法错误”。 我的JOIN语句正确吗? 我玩过(),“”等,但没有成功。 我已经检查过,并且表名正确(订单,客户,订单项)字段名称也拼写正确。
我喜欢使用带有空格分隔符的数组和Join方法。 这样可以确保我不会错过任何空格(@ McAdam133指出您确实有空格)。
Dim aSql(1 To 6) As String
aSql(1) = "SELECT O.OrderDate, COUNT(O.OrderID), SUM([L.QuantityOrdered]*[L.QuotedPrice]) AS TotalCost"
aSql(2) = "FROM (Customers C INNER JOIN Orders O ON C.CustomerID = O.CustomerID)"
aSql(3) = "INNER JOIN LineItems L ON O.OrderID = L.OrderID"
aSql(4) = "WHERE C.CustomerID = " & CustomerID
aSql(5) = "GROUP BY O.OrderDate"
aSql(6) = "ORDER BY O.OrderDate"
Set rs = CurrentProject.Connection.Execute(Join(aSql, Space(1)))
这是我对不起作用的内部联接的建议。 在Access中创建一个查询,并查看它生成的SQL。 它可能不是最漂亮的SQL,但可以帮助您确定问题所在。 如果将“客户”,“订单”和“订单项”放置在查询窗口中,则在必要时绘制箭头(默认情况下可能会出现在其中),然后在其中放置几个字段,Access会生成类似
SELECT Orders.OrderID, Orders.OrderDate, LineItems.QuantityOrdered, LineItems.QuotedPrice
FROM (Customers INNER JOIN Orders ON Customers.CustomerID = Orders.CustomerID) INNER JOIN LineItems ON Orders.OrderID = LineItems.OrderID;
这不会对任何内容进行分组或使用别名,但可以为您提供有效的说明。 然后,您可以使用别名和分组进行修改,并进行测试。
从您的示例:
& "FROM (((Customers C INNER JOIN Orders O ON C.CustomerID = O.CustomerID) " _
这条线很好。 您要使用客户的主键(可能是订单中的外键)加入订单中的客户。
& "INNER JOIN ON O.OrderID = O.CustomerID) INNER JOIN LineItems as L " _
我不确定第一个联接要完成什么,但是正如@OpiesDad所说,这不是您想要的。 您已经在第一行中成功加入了Customers和Orders,因此您可以获取该联接的结果并将其联接到LineItems(上面的aSql(3))。 第二个联接(到LineItems)看起来不错。
您可以在一个以上的字段上连接两个表。 就像您有两个客户表,并且想查看是否有任何重叠。
FROM Wholesale INNER JOIN Retail ON Wholesale.CustomerName = Retail.CustName AND Wholesale.State = Retail.StateOrProvince
根据所显示的结构,您在所有表中都有非常独特的主键,因此不必在多个字段上进行联接。
最后,您要在OrderID上分组。 它不会引起错误,但也不会做任何事情。 您可以在SELECT部分的聚合函数中使用OrderID。 您应该汇总要汇总的字段,并按不汇总的字段分组。
在INNER JOIN
的表中创建别名时,必须使用AS
:
' Define SQL statement to get order info for selected product.
SQL = "SELECT O.OrderDate, COUNT(O.OrderID), SUM(L.QuantityOrdered * L.QuotedPrice) AS [TotalCost] " _
& "FROM (((Customers as C INNER JOIN Orders O ON C.CustomerID = O.CustomerID) " _
& "INNER JOIN ON O.OrderID = O.CustomerID) INNER JOIN LineItems as L " _
& "ON O.OrderID = L.OrderID)" _
& "WHERE O.CustomerID =" & CustomerID & " " _
& "GROUP BY O.OrderDate, O.OrderID" _
& "ORDER BY O.OrderDate;"
当然,请使用;
终止该语句;
。
您遇到的问题是您尝试执行的联接没有意义。
我们首先获取相关订单,然后添加订单项,因为这将使说明更加简单。
为此,您需要SQL:
SELECT C.CustomerID, C.CustomerName, O.OrderID, O.OrderDate
FROM Customers C INNER JOIN Orders O ON C.CustomerID = O.CustomerID
WHERE C.CustomerID = 15
ORDER By O.OrderDate
请注意,这假设您要查找的客户的ID为15。
这将为您提供所请求客户的所有按升序排列的订单列表。
如果需要订单项,则还需要链接到此表:
SELECT C.CustomerID, C.CustomerName, O.OrderId, O.OrderDate
, SUM(L.QuantityOrdered * L.QuotedPrice) AS [TotalCost]
FROM ((Customers C INNER JOIN Orders O ON C.CustomerID = O.CustomerID)
INNER JOIN LineItems L ON O.OrderID = L.OrderID)
WHERE C.CustomerID = 15
GROUP BY C.CustomerID, C.CustomerName, O.OrderID, O.OrderDate
ORDER BY O.OrderDate
这可能是您要查找的查询。 您列出的第二个INNER JOIN是多余的,没有任何意义。 您不想将OrderID与CustomerID匹配,而是想要与该客户匹配的订单列表。 C到O上的第一个INNER JOIN已经创建了这个。 where子句将客户表限制为一个客户。
要将其放入代码中,只需将表单中的“ 15”替换为“ CustomerID”即可。
此外,根据McAdam的评论,您在几个地方缺少空格。 要解决此问题,我建议将所有空格放在行的开头,以便确保它们在那里(如下所述)。 最终代码应如下所示(从输出中删除客户信息):
SQL = "SELECT O.OrderDate, O.OrderID" _
& ", SUM(L.QuantityOrdered * L.QuotedPrice) AS [TotalCost]" _
& " FROM ((Customers C INNER JOIN Orders O ON C.CustomerID = O.CustomerID)" _
& " INNER JOIN LineItems L ON O.OrderID = L.OrderID)" _
& " WHERE O.CustomerID =" & CustomerID _
& " GROUP BY O.OrderDate, O.OrderID" _
& " ORDER BY O.OrderDate"
您似乎也不实际想要orderID的数量,所以我将其删除了,因为它也没有太大意义。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.