将WHERE语句添加到引用ODBC链接

时间:2016-01-21 16:05:34

标签: sql subquery ms-access-2007

原帖

给出两个如下结构的表:

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"可以有0到多个组件。

在我想要的查询中是否有某些东西可以忽略,或者这是否需要sku方法?

编辑#1 - 回答安德烈提出的问题

Screenshot of my personal issue.

  • 完整的错误消息为UNION

  • Invalid operation.sku的主键,共有1426条记录。

  • t1包含约446,000条记录,主键是t2sku的合并。

  • 实际的part语句是部分搜索。所有"轮子"具有相同的后缀但不同的组件项目编号。

此外,我在Access 2007中,它可能是与软件版本相关的问题。

将子查询放入临时表是有效的,但目标是避免该过程。

编辑#2 - 我环境中的一个缺陷

My test case results

我创建了一个与我在这里发布的测试场景完全相同的测试场景,我得到的结果与Andre相同。此时,将这些结果与临时表方法确实有效的事实相结合,我被认为是查询复杂性和记录访问的问题。尽管错误消息不是典型的WHERE消息。

编辑#3 - 深入挖掘"复杂性"

我的下一个测试是使where子句更简单。可悲的是,我工作的系统每天午餐更新,我目前无法访问任何数据服务器。我希望今天稍后更新我的进展。

编辑#4 - 替换部分搜索

好的,我们已经退出会议并准备好了。我刚刚使用三个不同的Query is too complex.子句运行了六个查询:

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"

Tl; dr 除非过滤器导致子查询返回0条记录,否则过滤器细节没有区别。

编辑#5 - 一个有趣的结果

在尝试所有可能的解决方案并测试我能做的一切的想法下,我创建了一个本地临时表,其中包含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 | ###### | | ... |... | ... | | (~25MB)的每个字段和每个记录。引用此表而不是t2的ODBC链接可以使用部分搜索查询(t2)。我正在更新此问题的标题,以反映该问题特定于链接表。

2 个答案:

答案 0 :(得分:0)

我将示例数据复制到Access 2010并运行查询,它没有问题。

datasheet view of query

您收到的完整错误消息是什么? (“非常精细的无效操作。”)

你的桌子里有多少条记录?

sku中的t1主键是什么?

无论如何,我建议将子查询更改为:

SELECT sku, quant
FROM t2
WHERE part = "wheel"
只有部分搜索才需要

LIKE

答案 1 :(得分:0)

解决方法

我设计了一组查询,这些查询使用我UNION语句的原始内容之一。希望这允许任何偶然发现此问题的人节省一些时间。

设置UNION

我最初的问题是没有办法只选择轮记录,然后将它们连接到空记录,因为(使用t1作为示例)船在t2中有部分,但没有一个是轮子。我不得不首先设计一种方法来查看哪些产品没有使用过滤器。

我的中间解决方案:

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

此查询返回t1的每条记录,后跟一个数字,该数字基于该项目编号的部件列表中的wheel条记录数。如果t2中没有记录" wheel"在字段part中,查询为记录返回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语句:

sku  | desc  | fcst  | wheels | wheelfcst
0001 | Car   | 10000 | 4      | 40000
0003 | Bike  | 7500  | 2      | 15000
...  | ...   | ...   | ...    | ...
0002 | Boat  | 5000  |        |
0004 | Shirt | 2500  |        |
...  | ...   | ...   | ...    | ...