将 WHERE 语句添加到引用 ODBC link 的子查询时,访问查询失败
Access query fails when WHERE statement is added to subquery referencing ODBC link
原始post
给定两个 table 结构如下:
t1 (finished goods) t2 (component parts)
sku | desc | fcst sku | part | quant
0001 | Car | 10000 0001 | wheel | 4
0002 | Boat | 5000 0001 | door | 2
0003 | Bike | 7500 0002 | hull | 1
0004 | Shirt | 2500 0002 | rudder | 1
... | ... | ... 0003 | wheel | 2
0005 | rotor | 2
... | ... | ...
我正在尝试将车轮要求附加到预测中,同时将所有记录保留在预测中。我的结果如下所示:
sku | desc | fcst | wheels | wheelfcst
0001 | Car | 10000 | 4 | 40000
0002 | Boat | 5000 | |
0003 | Bike | 7500 | 2 | 15000
0004 | Shirt | 2500 | |
... | ... | ... | ... | ...
在我看来,解决此问题的最有效方法类似于以下查询:
SELECT
t1.sku,
t1.desc,
t1.fcst,
q.quant as wheels,
t1.fcst * q.quant as wheelfcst
FROM
t1
LEFT JOIN
(
SELECT *
FROM t2
WHERE part LIKE "wheel"
)
as q
ON t1.sku = q.sku
问题是当 运行 时它给出了一个非常复杂的 Invalid Operation.
错误。
如果我删除 WHERE
语句:我得到了所需的轮子部件,但我也拉了门、船体和方向舵数量。
如果我将 WHERE
语句移动到主查询 (WHERE q.part LIKE "wheel"
):我只看到包含轮子的货物,但结果中缺少船。
我考虑过一个UNION
语句,把前面提到的将WHERE
移出子查询(WHERE q.part LIKE "wheel"
)的结果,但似乎没有抓取每个没有轮子组件的最终项目的好方法,因为每个 sku
可以有 0 到多个组件。
在我想要的查询中是否有我忽略的东西,或者这是否需要 UNION
方法?
编辑 #1 - 回答 Andre
提出的问题
完整的错误信息是Invalid operation.
sku
是t1
的主键,共有1426条记录
t2
包含 ~446,000 条记录,主键是 sku
和 part
的组合。
实际的WHERE
语句是部分搜索。所有 "wheels" 都具有相同的后缀,但组件项目编号不同。
另外我是Access 2007,可能是软件版本问题
将子查询变为临时 table 可行,但目标是避免该过程。
编辑 #2 - 我环境中的缺陷
我创建了一个与我在此处 post 编辑的相同的测试场景,我得到了与 Andre 相同的结果。在这一点上,将这些结果与临时 table 方法确实有效的事实相结合,我相信这是查询复杂性和记录访问的问题。尽管错误消息不是典型的 Query is too complex.
消息。
编辑 #3 - 深入挖掘 "Complexity"
我的下一个测试是使 where 子句更简单。可悲的是,我工作的系统每天午餐时更新,目前我无法访问任何数据服务器。我希望在今天晚些时候更新我的进度。
编辑 #4 - 替换部分搜索
好的,我们开完会回来准备出发了。我只有 运行 六个查询,其中包含三个不同的 WHERE
子句:
WHERE part LIKE "*heel"
/ WHERE component_item LIKE "*SBP"
(原大号)
适用于小规模测试,Invalid operation
适用于大规模测试。
WHERE part LIKE "wheel"
/ WHERE component_item LIKE "VALIDPART"
(原小尺度)
适用于小规模测试,Invalid operation
适用于大规模测试。
WHERE part LIKE "wh33l"
/ WHERE component_item LIKE "NOTVALIDPART"
(Where语句没有return任何记录)
Small Scale
sku | desc | fcst | wheels | wheelfcst
0001 | Car | 10000 | |
0002 | Boat | 5000 | |
0003 | Bike | 10000 | |
0004 | Shirt | 5000 | |
Large Scale
sku |description |forecast |component_item |dip_rate
#####|RealItem1 | ###### | |
#####|RealItem2 | ###### | |
#####|RealItem3 | ###### | |
... |... | ... | |
Tl;dr 过滤器细节没有影响,除非过滤器产生一个 returned 0 条记录的子查询。
编辑 #5 - 一个有趣的结果
在尝试所有可能的解决方案并尽我所能进行测试的想法下,我创建了一个本地临时文件 table,其中包含 t2
(~25MB) 中的每个字段和每条记录。引用此 table 而不是 ODBC link 到 t2
适用于部分搜索查询 (WHERE component_item LIKE "*SBP"
)。我正在更新此问题的标题以反映该问题特定于 linked table.
我将示例数据复制到 Access 2010 和 运行 查询,它没有问题。
您收到的完整错误消息是什么? ("very elaborate Invalid Operation.")
你的表中有多少条记录?
sku
是t1
中的主键吗?
无论如何,我建议将子查询更改为:
SELECT sku, quant
FROM t2
WHERE part = "wheel"
LIKE
仅用于部分搜索。
解决方法
我设计了一组查询,这些查询使用我对 UNION
语句的一个原始预感。希望这能让任何偶然发现这个问题的人节省一点时间。
正在设置 UNION
我最初的问题是没有办法只 select 轮记录然后将它们加入空记录,因为(以 t1
为例)船有零件t2
,但其中 none 是轮子。我必须首先设计一种方法来查看哪些产品有轮子而不使用过滤器。
我的中间方案:
Query: t1haswheel
SELECT
t1.sku,
t1.desc,
t1.fcst,
SUM(
IF(
t2.part = "wheel",
1, 0
) as haswheel
FROM
t1
LEFT JOIN
(
SELECT *
FROM t2
WHERE part LIKE "wheel"
)
as q
ON t1.sku = q.sku
GROUP BY
t1.sku,
t1.desc,
t1.fcst
此查询 returns 来自 t1
的每条记录,后跟一个基于该项目编号的部件列表中 wheel
记录数的数字。如果 t2
中没有记录,字段 part
中有 "wheel",则查询 returns 0 记录。此列表是我在原始问题中的 UNION
语句所需要的。
UNION
-把它们放在一起
此时,所需要的只是一个 UNION
,它使用来自先前查询 (haswheel
) 的求和字段。
SELECT
q1.sku,
q1.desc,
q1.fcst,
t2.quant,
q1.fcst * t2.quant as wheelfcst
FROM
t1haswheel as q1
LEFT JOIN t2
ON q1.sku = t2.sku
WHERE
q1.haswheel > 0 AND
t2.part = "wheel"
UNION ALL
SELECT
q1.sku,
q1.desc,
q1.fcst,
null,
null
FROM
t1haswheel as q1
WHERE q1.haswheel = 0
这从带轮子的记录中提取正确的结果,然后附加不带轮子的记录,同时从不在引用 ODBC 链接的子查询中使用 WHERE
语句 table:
sku | desc | fcst | wheels | wheelfcst
0001 | Car | 10000 | 4 | 40000
0003 | Bike | 7500 | 2 | 15000
... | ... | ... | ... | ...
0002 | Boat | 5000 | |
0004 | Shirt | 2500 | |
... | ... | ... | ... | ...
原始post
给定两个 table 结构如下:
t1 (finished goods) t2 (component parts)
sku | desc | fcst sku | part | quant
0001 | Car | 10000 0001 | wheel | 4
0002 | Boat | 5000 0001 | door | 2
0003 | Bike | 7500 0002 | hull | 1
0004 | Shirt | 2500 0002 | rudder | 1
... | ... | ... 0003 | wheel | 2
0005 | rotor | 2
... | ... | ...
我正在尝试将车轮要求附加到预测中,同时将所有记录保留在预测中。我的结果如下所示:
sku | desc | fcst | wheels | wheelfcst
0001 | Car | 10000 | 4 | 40000
0002 | Boat | 5000 | |
0003 | Bike | 7500 | 2 | 15000
0004 | Shirt | 2500 | |
... | ... | ... | ... | ...
在我看来,解决此问题的最有效方法类似于以下查询:
SELECT
t1.sku,
t1.desc,
t1.fcst,
q.quant as wheels,
t1.fcst * q.quant as wheelfcst
FROM
t1
LEFT JOIN
(
SELECT *
FROM t2
WHERE part LIKE "wheel"
)
as q
ON t1.sku = q.sku
问题是当 运行 时它给出了一个非常复杂的 Invalid Operation.
错误。
如果我删除 WHERE
语句:我得到了所需的轮子部件,但我也拉了门、船体和方向舵数量。
如果我将 WHERE
语句移动到主查询 (WHERE q.part LIKE "wheel"
):我只看到包含轮子的货物,但结果中缺少船。
我考虑过一个UNION
语句,把前面提到的将WHERE
移出子查询(WHERE q.part LIKE "wheel"
)的结果,但似乎没有抓取每个没有轮子组件的最终项目的好方法,因为每个 sku
可以有 0 到多个组件。
在我想要的查询中是否有我忽略的东西,或者这是否需要 UNION
方法?
编辑 #1 - 回答 Andre
提出的问题完整的错误信息是
Invalid operation.
sku
是t1
的主键,共有1426条记录t2
包含 ~446,000 条记录,主键是sku
和part
的组合。实际的
WHERE
语句是部分搜索。所有 "wheels" 都具有相同的后缀,但组件项目编号不同。
另外我是Access 2007,可能是软件版本问题
将子查询变为临时 table 可行,但目标是避免该过程。
编辑 #2 - 我环境中的缺陷
我创建了一个与我在此处 post 编辑的相同的测试场景,我得到了与 Andre 相同的结果。在这一点上,将这些结果与临时 table 方法确实有效的事实相结合,我相信这是查询复杂性和记录访问的问题。尽管错误消息不是典型的 Query is too complex.
消息。
编辑 #3 - 深入挖掘 "Complexity"
我的下一个测试是使 where 子句更简单。可悲的是,我工作的系统每天午餐时更新,目前我无法访问任何数据服务器。我希望在今天晚些时候更新我的进度。
编辑 #4 - 替换部分搜索
好的,我们开完会回来准备出发了。我只有 运行 六个查询,其中包含三个不同的 WHERE
子句:
WHERE part LIKE "*heel"
/ WHERE component_item LIKE "*SBP"
(原大号)
适用于小规模测试,Invalid operation
适用于大规模测试。
WHERE part LIKE "wheel"
/ WHERE component_item LIKE "VALIDPART"
(原小尺度)
适用于小规模测试,Invalid operation
适用于大规模测试。
WHERE part LIKE "wh33l"
/ WHERE component_item LIKE "NOTVALIDPART"
(Where语句没有return任何记录)
Small Scale
sku | desc | fcst | wheels | wheelfcst
0001 | Car | 10000 | |
0002 | Boat | 5000 | |
0003 | Bike | 10000 | |
0004 | Shirt | 5000 | |
Large Scale
sku |description |forecast |component_item |dip_rate
#####|RealItem1 | ###### | |
#####|RealItem2 | ###### | |
#####|RealItem3 | ###### | |
... |... | ... | |
Tl;dr 过滤器细节没有影响,除非过滤器产生一个 returned 0 条记录的子查询。
编辑 #5 - 一个有趣的结果
在尝试所有可能的解决方案并尽我所能进行测试的想法下,我创建了一个本地临时文件 table,其中包含 t2
(~25MB) 中的每个字段和每条记录。引用此 table 而不是 ODBC link 到 t2
适用于部分搜索查询 (WHERE component_item LIKE "*SBP"
)。我正在更新此问题的标题以反映该问题特定于 linked table.
我将示例数据复制到 Access 2010 和 运行 查询,它没有问题。
您收到的完整错误消息是什么? ("very elaborate Invalid Operation.")
你的表中有多少条记录?
sku
是t1
中的主键吗?
无论如何,我建议将子查询更改为:
SELECT sku, quant
FROM t2
WHERE part = "wheel"
LIKE
仅用于部分搜索。
解决方法
我设计了一组查询,这些查询使用我对 UNION
语句的一个原始预感。希望这能让任何偶然发现这个问题的人节省一点时间。
正在设置 UNION
我最初的问题是没有办法只 select 轮记录然后将它们加入空记录,因为(以 t1
为例)船有零件t2
,但其中 none 是轮子。我必须首先设计一种方法来查看哪些产品有轮子而不使用过滤器。
我的中间方案:
Query: t1haswheel
SELECT
t1.sku,
t1.desc,
t1.fcst,
SUM(
IF(
t2.part = "wheel",
1, 0
) as haswheel
FROM
t1
LEFT JOIN
(
SELECT *
FROM t2
WHERE part LIKE "wheel"
)
as q
ON t1.sku = q.sku
GROUP BY
t1.sku,
t1.desc,
t1.fcst
此查询 returns 来自 t1
的每条记录,后跟一个基于该项目编号的部件列表中 wheel
记录数的数字。如果 t2
中没有记录,字段 part
中有 "wheel",则查询 returns 0 记录。此列表是我在原始问题中的 UNION
语句所需要的。
UNION
-把它们放在一起
此时,所需要的只是一个 UNION
,它使用来自先前查询 (haswheel
) 的求和字段。
SELECT
q1.sku,
q1.desc,
q1.fcst,
t2.quant,
q1.fcst * t2.quant as wheelfcst
FROM
t1haswheel as q1
LEFT JOIN t2
ON q1.sku = t2.sku
WHERE
q1.haswheel > 0 AND
t2.part = "wheel"
UNION ALL
SELECT
q1.sku,
q1.desc,
q1.fcst,
null,
null
FROM
t1haswheel as q1
WHERE q1.haswheel = 0
这从带轮子的记录中提取正确的结果,然后附加不带轮子的记录,同时从不在引用 ODBC 链接的子查询中使用 WHERE
语句 table:
sku | desc | fcst | wheels | wheelfcst
0001 | Car | 10000 | 4 | 40000
0003 | Bike | 7500 | 2 | 15000
... | ... | ... | ... | ...
0002 | Boat | 5000 | |
0004 | Shirt | 2500 | |
... | ... | ... | ... | ...