我有一些SQL,在这个问题中添加所有语句太多了,我正在努力改进以消除系统速度降低。
在部分PL / SQL中,有一个 AND Exists 子句,其中包含 AND Not Exists 子句。
这两个条款都包含 Case 语句。在case语句的 End 部分之后,有一个 IS NOT NULL 或 IS NULL 语句。多年来使用PL / SQL这是我第一次看到这种语法,我自愿承认不理解它。整个 AND Exists 子句显示在下方,非常感谢帮助。
AND EXISTS (
SELECT Distinct PROJECTID
From Milestone_History MH,
Project_Milestone PM
Where MH.MilestoneId = PM.ID
AND MH.Projectid = PR.ID
AND ((UPPER(PM.Description) = 'FINAL BUILD INVOICE INSTRUCTIONS ISSUED') OR
(UPPER(PM.Description) = 'FEASIBILITY STUDY REQUIRED') OR
(UPPER(PM.Description) = 'PROJECT COMPLETE'))
AND (case when UPPER(PM.Description) = 'FEASIBILITY STUDY REQUIRED' then
Actual
End IS NOT NULL
AND
case
when UPPER(PM.Description) = 'PROJECT COMPLETE' then
MH.Actual
end IS NULL)
AND NOT EXISTS
(SELECT Distinct MH2.ProjectID
From Milestone_History MH2, Project_Milestone PM2
Where MH2.MilestoneId = PM2.ID
And MH2.ProjectID = MH.ProjectID
AND case
when UPPER(PM2.Description) = 'PROJECT COMPLETE' then -
MH2.Actual
end IS NOT NULL))
答案 0 :(得分:3)
将CASE...END
视为单个表达式。您可以使用括号来更好地理解:
(case when UPPER(PM.Description) = 'FEASIBILITY STUDY REQUIRED'
then Actual
End) IS NOT NULL
当且仅当NOT NULL
找到匹配且CASE
不为空时,此特定表达式为Actual
。
这可以改写为:
(UPPER(pm.description) = 'FEASIBILITY STUDY REQUIRED'
AND actual IS NOT NULL)
以下声明可以改写为:
(UPPER(PM.Description) != 'PROJECT COMPLETE'
OR PM.Description IS NULL
OR actual IS NULL)
这两个陈述明显重叠:Descrition
只能有一个值。当我们合并它们时,剩下的就不多了:
(SELECT Distinct PROJECTID
From Milestone_History MH,
Project_Milestone PM
Where MH.MilestoneId = PM.ID
AND MH.Projectid = PR.ID
AND UPPER(PM.Description) = 'FEASIBILITY STUDY REQUIRED'
AND actual IS NOT NULL
AND NOT EXISTS
(SELECT Distinct MH2.ProjectID
From Milestone_History MH2, Project_Milestone PM2
Where MH2.MilestoneId = PM2.ID
And MH2.ProjectID = MH.ProjectID
AND PM2.Description = 'PROJECT COMPLETE'
AND MH2.Actual IS NOT NULL)
)
我认为在单个案例中使用CASE
会有点误导。
作者被误导了CASE
的行为,或者这是在未经清理的情况下一直更新的残余代码。
答案 1 :(得分:2)
前两个条件:
Where MH.MilestoneId = PM.ID
AND MH.Projectid = PR.ID
- 连接子查询中的两个表,并将子查询加入主查询。
接下来的三个条件:
AND (UPPER(PM.Description) = 'FINAL BUILD INVOICE INSTRUCTIONS ISSUED' OR
UPPER(PM.Description) = 'FEASIBILITY STUDY REQUIRED' OR
UPPER(PM.Description) = 'PROJECT COMPLETE')
- 确保Description
是三个值中的一个。
然而下一个条件是:
AND case when UPPER(PM.Description) = 'FEASIBILITY STUDY REQUIRED'
then Actual End IS NOT NULL
- 虽然本身可以,但与之前三个条件中的两个相矛盾。写成CASE WHEN condition THEN value END IS NOT NULL
的表达式实质上是说两者 condition
必须为真(否则CASE子句评估为NULL)和该值不得为NULL;它可以改写为:
AND UPPER(PM.Description) = 'FEASIBILITY STUDY REQUIRED'
AND Actual IS NOT NULL
- 更清晰,更简洁(并排除前一个括号内的三个条件中的两个)。
下一个条件:
AND case when UPPER(PM.Description) = 'PROJECT COMPLETE'
then MH.Actual end IS NULL
- 虽然(再次)OK本身,但由于先前的条件,基本上是多余的;它可以改写为:
AND (UPPER(PM.Description) <> 'PROJECT COMPLETE' OR MH.Actual IS NULL)
- 再次,更清晰,更简洁。这也是不必要的,因为之前的条件UPPER(PM.Description) = 'FEASIBILITY STUDY REQUIRED'
确保UPPER(PM.Description) <> 'PROJECT COMPLETE'
始终为真。
NOT EXISTS
子句可以作为单独的子句包含在EXISTS
子句之外的主查询末尾,只需将And MH2.ProjectID = MH.ProjectID
更改为
And MH2.ProjectID = PR.ProjectID
- 但是,查询应该使用NOT EXISTS
子句中的EXISTS
子句执行得更快一些,因为只有EXISTS
子句的其余部分是真。
与先前的IS NOT NULL条件一样,表达式为:
AND case when UPPER(PM2.Description) = 'PROJECT COMPLETE'
then MH2.Actual end IS NOT NULL
- 可以改写为:
AND UPPER(PM2.Description) = 'PROJECT COMPLETE'
AND MH2.Actual IS NOT NULL
所以整个条款可以改写为:
AND EXISTS
(SELECT Distinct PROJECTID
From Milestone_History MH, Project_Milestone PM
Where MH.MilestoneId = PM.ID
AND MH.Projectid = PR.ID
AND UPPER(PM.Description) = 'FEASIBILITY STUDY REQUIRED'
AND Actual IS NOT NULL
AND NOT EXISTS
(SELECT Distinct MH2.ProjectID
From Milestone_History MH2, Project_Milestone PM2
Where MH2.MilestoneId = PM2.ID
AND UPPER(PM2.Description) = 'PROJECT COMPLETE'
AND MH2.Actual IS NOT NULL
)
)