我对DB2有点新,并且在开发查询时遇到问题。我创建了一个用户定义的函数,它返回一个数据表,然后我想要在更大的select语句中加入和选择。我正在研究一个敏感的数据库,所以下面的查询不是我真正运行的,但它几乎完全像它(没有其他10个连接我必须做大声笑)。
select
A.customerId,
A.firstname,
A.lastname,
B.orderId,
B.orderDate,
F.currentLocationDate,
F.currentLocation
from
customer A
INNER JOIN order B
on A.customerId = B.customerId
INNER JOIN table(getShippingHistory(B.customerId)) as F
on B.orderId = F.orderId
where B.orderId = 35
如果我在没有where子句(或其他不检查ID的where子句)的情况下运行此查询,则此方法很有用。当我包含where子句时,我收到以下错误:
准备58004期间出错(-901)[IBM] [CLI驱动程序] [DB2 / LINUXX8664] SQL0901N由于非严重系统,SQL语句失败 错误。可以处理后续的SQL语句。 (原因“坏计划; 未解决的QNC发现“。)SQLSTATE = 58004
我已将问题跟踪到事实,即我正在使用参数的连接条件之一(B.customerId)。我已经通过用有效的customerId替换B.customerId来验证这一事实,并且查询效果很好。问题是,我在调用此查询时不知道customerId。我只知道orderId(在这个例子中)。
有关如何重组这一点的任何想法,所以我只能打一个电话来获取所有信息?我知道计划是问题b / c在调用函数之前,customerId没有得到解决。
答案 0 :(得分:0)
因此,如果我理解正确,函数getShippingHistory(customerId)将返回一个表。
如果您使用单个客户ID调用该表,则表格会在您的查询中加入上面没有任何问题。
但是你上面写的查询方式,你要求db2为查询返回的每一行调用函数(即每个与你的连接和条件匹配的b.customerId)。
所以我不确定你期望的是什么行为,因为你要求的是查询中每一行的表格,db2(也是我)可以弄清楚结果应该是什么样的
因此,在重构查询方面,请考虑在涉及多个客户ID时如何更改getShippingHistory逻辑。
答案 1 :(得分:0)
我发现最好的解决方案(给定当前的查询结构)是使用LEFT连接而不是INNER连接,以强制连接的LEFT部分发生,这将在获得时将customerId解析为值到函数调用。
select
A.customerId,
A.firstname,
A.lastname,
B.orderId,
B.orderDate,
F.currentLocationDate,
F.currentLocation
from
customer A
INNER JOIN order B
on A.customerId = B.customerId
LEFT JOIN table(getShippingHistory(B.customerId)) as F
on B.orderId = F.orderId
where B.orderId = 35