【发布时间】:2010-04-22 15:10:04
【问题描述】:
我遇到了一个非常奇怪的问题,我有一个复杂的视图,当我在特定列上查询时返回不正确的数据。
举个例子:
select empname
, has_garnishment
from timecard_v2
where empname = 'Testerson, Testy';
这将返回单个结果 'Testerson, Testy', 'N'
但是,如果我使用查询:
select empname
, has_garnishment
from timecard_v2
where empname = 'Testerson, Testy'
and has_garnishment = 'Y';
这会返回单个结果 'Testerson, Testy', 'Y'
第二个查询应该返回第一个查询的子集,但它返回不同的答案。
当我使用查询时:
select empname
, has_garnishment
from timecard_v2
where empname = 'Testerson, Testy'
and has_garnishment = 'N';
我没有得到任何结果
我已经剖析了视图并确定视图定义的这一部分是问题出现的地方,即使我采用 sql 定义并将其作为直接查询运行(注意,我删除了所有 select 子句为了清楚起见,除了感兴趣的部分,在完整查询中所有连接表都是必需的):
SELECT
e.fullname empname ,
NVL2(ded.has_garn, 'Y', 'N') has_garnishment
FROM timecard tc ,
orderdetail od ,
orderassign oa ,
employee e ,
employee3 e3 ,
customer10 c10 ,
order_misc om,
(SELECT COUNT(*) has_garn,
v_ssn
FROM deductions
WHERE yymmdd_stop = 0
OR (LENGTH(yymmdd_stop) = 7
AND to_date(SUBSTR(yymmdd_stop, 2), 'YYMMDD') > sysdate)
GROUP BY v_ssn
) ded
WHERE oa.lrn(+) = tc.lrn_order
AND om.lrn(+) = od.lrn
AND od.orderno = oa.orderno
AND e.ssn = tc.ssn
AND c10.custno = tc.custno
AND e.lrn = e3.lrn
AND e.ssn = ded.v_ssn(+)
关于“ded”子查询的定义有一点需要注意。 v_ssn 字段是 deductions 表上的虚拟字段。
我不是 DBA,我是软件开发人员,但我们最近失去了 DBA,而新的 DBA 仍在加快速度,所以我正在尝试调试这个问题。话虽如此,请比其他预言机专家更彻底地解释一下。
谢谢
【问题讨论】:
-
DED 子查询似乎可以使用一些格式和 cmets 来帮助使其更受支持。但我怀疑我在阅读 SQL 时遇到的麻烦与问题有关。为了获得更多信息,请尝试查看 SQL 语句并添加“empname = 'Testerson, Testy'”限制器。你得到了什么结果?
-
我有兴趣查看两个查询的执行计划给出不一致的结果。在 SQLPlus 中,输入
set autotrace traceonly explain然后执行查询。 -
我想知道当您输入第一个查询并添加 had_garnishment = 'N' 时会得到什么
-
戴夫,我会尽快获取执行计划并将其添加到问题中。 Jay 和 MJB,我在问题中添加了您问题的答案。谢谢大家
-
只是为了确保我理解,当 ded 子查询外连接但为空时,NVL2 返回 Y,对吗?当在正确的范围内有一些扣除时,N?还有一个请求,你能做'select has_garnishment,count(*) from timecard_v2 group by has_garnishment'吗?我还在想。