我遇到过两个版本的SQLRPGLE程序,并看到代码发生了如下变化:
在:
Exec Sql SELECT 'N'
INTO :APRFLG
FROM LG751F T1
INNER JOIN LG752F T2
ON T1.ISBOLN = T2.IDBOLN AND
T1.ISITNO = T2.IDMDNO
WHERE T2.IDVIN = :M_VIN AND
T1.ISAPRV <> 'Y';
后:
Exec Sql SELECT case
when T1.ISAPRV <> 'Y' then 'N'
else T1.ISAPRV
end as APRFLG
INTO :APRFLG
FROM LG751F T1
join LG752F T2
ON T1.ISBOLN = T2.IDBOLN AND
T1.ISITNO = T2.IDMDNO
WHERE T2.IDVIN = :M_VIN AND
T1.ISAPRV <> 'Y'
group by T1.ISAPRV;
如果您发现代码的工作方式有何不同,请告诉我?第二个SQL有一个组,它应该是一个修复,以避免-811 SQLCod错误。除此之外,你们有没有发现任何差异?
答案 0 :(得分:0)
我没有找到令人信服的区别,除了添加组之外,还会产生抑制可能已输出的任何重复行的效果。
看起来用于查询的开发人员能够将其输出更改为有时为Y且有时为N,但忘记删除WHERE子句,该子句必然会强制大小写始终为true,因此始终输出N.当原始报告包含一些规范,例如“不包括员工萨卡里亚报告中的经理”,然后改为“实际上我们想知道员工是否是经理”时,通常会看到这种模式。什么是“员工不平等的经理”成为“当员工是经理然后......其他......”但是where子句需要删除才能产生任何效果
inner关键字已从join语句中消失,但总体而言,这也应该是非op
答案 1 :(得分:0)
它们都是编码不良的IMO的例子。
要求&#34;删除重复&#34;通常表示错误的语句设计和/或糟糕的数据库设计。
您似乎正在进行存在检查,在这种情况下,您应该使用EXISTS
谓词。
select 'N' into :APRFLG
from sysibm.sysdummy1
where exists (select 1
FROM LG751F T1
INNER JOIN LG752F T2
ON T1.ISBOLN = T2.IDBOLN
AND T1.ISITNO = T2.IDMDNO
WHERE
T2.IDVIN = :M_VIN
AND T1.ISAPRV <> 'Y');
就原始的两个语句而言,除了group by之外,唯一真正的区别是将列从JOIN
子句移动到WHERE
子句。但是,Db2 for i中的查询引擎将等效地重写两个语句并提出相同的计划;因为使用了内连接。
编辑,OP JOIN
和WHERE
在两个OP的语句中都相同。但我将把上述声明留作FYI。
答案 2 :(得分:0)
另一种选择就是像这样使用fetch first row only
:
Exec Sql
SELECT 'N'
INTO :APRFLG
FROM LG751F T1
JOIN LG752F T2
ON T1.ISBOLN = T2.IDBOLN AND
T1.ISITNO = T2.IDMDNO
WHERE T2.IDVIN = :M_VIN AND
T1.ISAPRV <> 'Y'
fetch first row only;
这更明显地表明你只需要一行而不是尝试使用分组,这就需要时髦的CASE
语句。但我确实喜欢Charles提供的EXISTS
方法,因为这是真正的目标,并且存在在那里使它变得清晰。
如果您的主管坚持GROUP BY
,您也可以GROUP BY 'N'
并且仍然遗漏CASE
声明。