Excel VBA SQLjoin语法错误

我正在写一个允许用户从列表框中select一个客户的子。 selectlogging为CustomerID(整型variables),并用于查询Access数据库文件。 然后子应该输出到Excel工作表销售信息关于指定的客户,特别是:

  1. 订购date
  2. 订单ID
  3. 总订单成本(定义为售出数量*售出价格)

访问文件有3个我需要的表格:Customers,Orders,LineItems

我下面的代码应该join客户ID到订单ID字段,然后再join订单ID,订单IDjoin到行项目中。

' 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语句正确吗? 我玩过(),“”等没有成功。 我已经检查并且表名是正确的(订单,客户,LineItems)字段名也拼写正确。

我喜欢用一个数组和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))) 

这是我的内部联接的build议不起作用。 在Access中创build一个查询并查看它生成的SQL。 它可能不是最漂亮的SQL,但它可以帮助你确定什么是错的。 如果您将Customers,Orders和LineItems放在查询窗口中,必要时绘制您的箭头(可能会在默认情况下),并在其中放置几个​​字段,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; 

这不分组任何东西或使用别名,但它给你一个工作的声明。 然后你可以修改别名和分组,一路testing。

从你的例子:

 & "FROM (((Customers C INNER JOIN Orders O ON C.CustomerID = O.CustomerID) " _ 

这条线是好的。 您正在使用客户的主键和订单中的外键(可能为外键)join客户订单。

 & "INNER JOIN ON O.OrderID = O.CustomerID) INNER JOIN LineItems as L " _ 

我不确定第一个连接是在做什么,但是@OpiesDad评论说这不是你想要的。 您已经成功地在第一行中join了客户和订单,因此您可以将该联结的结果join到LineItems(上面的aSql(3))中。 第二次连接(到LineItems)看起来很好。

您可以在多个字段中join两个表格。 就好像你有两张客户的桌子,你想看看是否有重叠。

 FROM Wholesale INNER JOIN Retail ON Wholesale.CustomerName = Retail.CustName AND Wholesale.State = Retail.StateOrProvince 

根据您所显示的结构,您的所有表格中都有唯一的主键,因此不需要连接多个字段。

最后,你在OrderID上进行分组。 这不是导致错误,但也没有做任何事情。 您在SELECT部分​​中使用了一个聚合函数中的OrderID。 你应该聚合你想聚合的字段,并按照你不聚合的字段进行分组。

当您在INNER JOIN的表中创build一个别名时,您必须使用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已经创build了这个。 where子句将客户表限制为只有一个客户。

要把它放在你的代码中,只需从表单中将“15”replace为“CustomerID”即可。

另外,根据McAdam的评论,你在几个地方缺less空间。 为了解决这个问题,我build议把所有的空格作为行的开始,以便确保它们在那里(如下所示)。 最终的代码应该如下所示(从输出中删除客户信息):

  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的数量,所以我把它拿出来,因为它也没有太多的意义。