这在Oracle的Having语句中是如何工作的



我正试图重写我继承的一个旧的Oracle SQL查询,其中有一部分我不理解。我的新版本出现了大约十几条额外的记录,我得出结论,这是因为原始版本中的HAVING子句正在过滤掉它们(我从新查询中删除了HAVING语句(。我不明白"不在(99,-99("在做什么。如果我删除NOT IN,我得到一个"ORA-00920:无效关系运算符";错误如果我把99,-99改成任何其他数字,记录仍然会被过滤掉。

有人知道NOT IN(99,-99(在做什么吗?我以前从未见过这样的事。

HAVING
(sum(case 
when (BD.EXPERIENCE_RATING_DESC) = 'RATED' 
AND BD.BENEFIT_CATEGORY<>'INTEREST' 
THEN CFCT.REPORTED_AMOUNT ELSE 0.00 END) 
NOT IN (99,-99)
AND sum(case 
when (BD.EXPERIENCE_RATING_DESC) = 'POOLED' 
AND BD.BENEFIT_CATEGORY<>'INTEREST' 
THEN CFCT.REPORTED_AMOUNT ELSE 0.00 END) 
NOT IN (99,-99)

这意味着大小写表达式的和可以是除99和-99之外的任何值。

您的代码,简化为Scott的EMP表:这些是每个部门的工资摘要:

SQL> select deptno, sum(sal) sumsal
2  from emp
3  group by deptno
4  order by deptno;
DEPTNO     SUMSAL
---------- ----------
10       8750
20      10875
30       9400

这就是您所拥有的,只是(正如我所说的(简化:我想省略第4行中指定的值:

SQL> select deptno, sum(sal) sumsal
2  from emp
3  group by deptno
4  having sum(sal) not in (8750, 9400)  --> this
5  order by deptno;
DEPTNO     SUMSAL
---------- ----------
20      10875
SQL>

正如您所看到的,结果包含除指定的值之外的任何内容。

如果SUM等于99或-99,则过滤掉该(聚合(行。

如果您将SUM值添加到SELECT列表中(如果它们还没有(,然后(暂时(通过删除单词"来反转HAVING子句,这可能更有意义;NOT";在这两种情况下。结果应该都是SUM值为99或-99的行。

IN列表只是将另一侧与进行比较的值列表

你通常会看到类似的东西

MY_COL in (1,2,3)

在只返回MY_COL为1、2或3的行的WHERE子句中。

您的语句位于HAVING子句中,因此它仍然需要一个谓词,而只是

sum(case 
when (BD.EXPERIENCE_RATING_DESC) = 'RATED' 
AND BD.BENEFIT_CATEGORY<>'INTEREST' 
THEN CFCT.REPORTED_AMOUNT ELSE 0.00 END) 

正在根据99和-99进行检查,如果是这两个值中的任何一个,则该行将被删除。

如果你去掉not,你会得到一个错误,因为你的谓词变成了sum(...),没有什么可比较的。

看起来您可以稍微清理一下having clause。这样做可能会使not in在中的作用更加明显

where bd.benefit_category <> 'INTEREST'
group by...
having sum(case when bd.experience_rating_desc in ('RATED','POOLED') then cfct.reported_amount end) not in (99,-99);

最新更新