前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Excel VBA SQL Join Syntax ErrorExcel VBA SQL 连接语法错误

Excel VBA SQL Join Syntax ErrorExcel VBA SQL 连接语法错误

作者头像
matinal
发布2023-10-13 16:47:51
1610
发布2023-10-13 16:47:51
举报
文章被收录于专栏:SAP TechnicalSAP Technical

【问题标题】:Excel VBA SQL Join Syntax ErrorExcel VBA SQL 连接语法错误 【发布时间】:2015-09-24 00:08:56 【问题描述】:

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

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

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

我下面的代码应该将客户 ID 连接到订单 ID 字段,然后将其与订单 ID 连接起来,并将订单 ID 连接到订单项上。

代码语言:javascript
复制
' 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)字段名称也拼写正确。

【问题讨论】:

  • ON 子句和 WHERE 之间或 group by 和 order by 之间没有空格。
  • 您不想将 orderid 加入 customerid ......这些是不匹配的不同 ID。只需删除该部分。此外,语法无论如何都不起作用。你不能做 INNER JOIN ON....你需要在 INNER JOIN 和 ON 之间放一个表。如果您想使用两个字段进行连接,则语法为“...C INNER JOIN Orders O ON C.CustomerID = O.Customer ID AND C.CustomerID = O.OrderID” 同样,我怀疑这实际上是您想要。
  • 感谢 OpiesDad,所以我应该创建一张桌子来容纳我需要的东西吗?我看不出答案那么复杂。你也是对的,我不认为我想加入使用两个字段。你能建议一些方向吗?我不明白为什么我不能将 OrderID 与 CustomerID 关联起来?它们确实有不同的值,但在“订单”表中,订单 ID 是主键,客户 ID 是外键。这似乎是最好的路线,因为表“ListItems”没有 CustomerID 作为外键。 (ListItems 有输出所需的订单详情)
  • 见下面的答案。 OrderID 已经与 CustomerID 相关,因为它们都在 Order Table 中。所以每条记录都有一个与它们相关的记录。 ListItems 将 OrderID 作为外键,因此通过 Order 表链接到 customerID。
  • 尝试将debug.print sql 直接放在它下面并检查VBE 的即时窗口(Ctrl+G)以查看您制作的内容。将其粘贴到空白的 Access 查询中并进行修改,直到它起作用,然后将更改传输回字符串构造并重新测试.

【解决方案1】:

我喜欢使用带有空格分隔符的数组和 Join 方法。这样可以确保我不会遗漏任何空格(@McAdam133 指出您这样做了)。

代码语言:javascript
复制
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,但它可以帮助您确定问题所在。如果您将客户、订单和 LineItems 放在查询窗口中,必要时绘制箭头(默认情况下可能会出现),并在其中放置几个​​字段,Access 将生成类似

代码语言:javascript
复制
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;

这不会对任何内容进行分组或使用别名,但它会为您提供工作声明。然后您可以使用别名和分组进行修改,并在此过程中对其进行测试。

从你的例子:

代码语言:javascript
复制
& "FROM (((Customers C INNER JOIN Orders O ON C.CustomerID = O.CustomerID) " _

这条线不错。您正在使用来自 Customers 的主键和可能在 Orders 中的外键加入订单中的客户。

代码语言:javascript
复制
& "INNER JOIN ON O.OrderID = O.CustomerID) INNER JOIN LineItems as L " _

我不确定第一次加入想要完成什么,但正如@OpiesDad 评论的那样,这不是你想要的。您已经在第一行成功地加入了 Customers 和 Orders,因此您可以获取该加入的结果并将其加入 LineItems(上面的 aSql(3))。第二个连接(到 LineItems)看起来不错。

您可以在多个字段上连接两个表。就像你有两张客户表,你想看看是否有任何重叠。

代码语言:javascript
复制
FROM Wholesale INNER JOIN Retail ON Wholesale.CustomerName = Retail.CustName AND Wholesale.State = Retail.StateOrProvince

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

最后,您将根据 OrderID 进行分组。它不会导致错误,但它也没有做任何事情。您在 SELECT 部分的聚合函数中使用 OrderID。您应该聚合您想要聚合的字段,并按您不聚合的字段进行分组。

【讨论】:

【解决方案2】:

INNER JOIN 中的表创建别名时,必须使用AS

代码语言:javascript
复制
' 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;"

可以肯定的是,用; 终止语句。

【讨论】:

  • 您不需要在 Access 中执行此操作,并且此代码仍然无法工作,因为它没有解决我没有时间制定的许多其他问题完整的答案。

【解决方案3】:

您遇到的问题是您尝试执行的连接没有意义。

让我们先获取相关订单,然后添加订单项,这样可以让解释更简单。

为此,您需要 SQL:

代码语言:javascript
复制
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。

这将为您提供所请求客户的所有订单的升序列表。

如果你想要订单项,那么你也需要链接到这个表格:

代码语言:javascript
复制
 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 的评论,您在几个地方缺少空格。为了解决这个问题,我建议将所有空格作为行首,这样你就可以确保它们在那里(如下所示)。最终代码应如下所示(从输出中删除客户信息):

代码语言:javascript
复制
 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 的计数,所以我把它去掉了,因为它也没有太大意义。

【讨论】:

  • 感谢您的回复 OpiesDad,您在第一条评论中暗示了答案,我推迟检查线程,直到完成(可以显示保存时间)。她的工作就像一颗宝石,丹克申
  • 如果它解决了问题并且您认为它是最好的,请将此标记为答案。很高兴能帮上忙。
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2023-10-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档