繁体   English   中英

Excel VBA SQL连接语法错误

[英]Excel VBA SQL Join Syntax Error

我正在写一个允许用户从列表框中选择客户的子程序。 选择记录为CustomerID(整数变量),并用于查询Access数据库文件。 然后,该子项应将有关指定客户的销售信息输出到excel工作表中,特别是:

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

访问文件具有我需要的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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM