简体   繁体   English

Oracle 中的 Have 语句中的 NOT IN 是如何工作的

[英]How does this NOT IN in a Having statement in Oracle work

I'm trying to rewrite an old Oracle SQL query I inherited and there is one part I don't understand.我正在尝试重写我继承的旧 Oracle SQL 查询,但有一部分我不明白。 My new version comes up with about a dozen extra records and I've concluded it's because the HAVING clause in the original version is filtering them out(I removed the HAVING statement from my new query).我的新版本提出了大约一打额外的记录,我得出结论,这是因为原始版本中的 HAVING 子句将它们过滤掉了(我从新查询中删除了 HAVING 语句)。 I don't understand what the 'NOT IN (99, -99) is doing.我不明白 'NOT IN (99, -99) 在做什么。 If I remove the NOT IN I get an 'ORA-00920: invalid relational operator" error. If I change the 99, -99 to any other number the records still get filtered out.如果我删除 NOT IN,我会收到“ORA-00920:无效关系运算符”错误。如果我将 99、-99 更改为任何其他数字,记录仍然会被过滤掉。

Does anyone understand what the NOT IN (99, -99) is doing?有谁明白 NOT IN (99, -99) 在做什么? I've never seen anything like this before.我以前从未见过这样的事情。

   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)

It means that sum of case expressions can be anything except 99 and -99.这意味着 case 表达式的总和可以是除 99 和 -99 之外的任何值。

Your code, simplified to Scott's EMP table: these are summaries of salaries per department:您的代码,简化为 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

This is what you have, just (as I said) simplified: I want to omit values specified in line #4:这就是你所拥有的,只是(正如我所说)简化了:我想省略第 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>

As you can see, result contains anything but values being specified.如您所见,结果包含指定值之外的任何内容

If either SUM equals 99 or -99, filter that (aggregated) row out.如果 SUM 等于 99 或 -99,则将该(聚合)行过滤掉。

It may make more sense if you add the SUM values to your SELECT list if they are not there already, and then (temporarily) reverse the HAVING clause by removing the word "NOT" in both cases.如果您将 SUM 值添加到您的 SELECT 列表(如果它们已经不存在),然后(暂时)通过在两种情况下删除单词“NOT”来反转 HAVING 子句,则可能更有意义。 The results should all be rows that have SUM values of either 99 or -99.结果应该都是 SUM 值为 99 或 -99 的行。

An IN list is just a list of values to compare the other side to IN列表只是要比较另一侧的值的列表

You would normally see something like你通常会看到类似的东西

MY_COL in (1,2,3)

in a WHERE clause which would only return rows where MY_COL was 1, 2 or 3.WHERE子句中,该子句仅返回MY_COL为 1、2 或 3 的行。

Your statement is in a HAVING clause so it is still expecting a predicate but simply你的语句在一个HAVING子句中,所以它仍然期待一个谓词,但只是

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

is being checked against 99 and -99 and if it either of those values the row is dropped.正在根据 99 和 -99 进行检查,如果是这些值中的任何一个,则该行将被删除。

If you take out the not in you get an error as you your predicate just becomes sum(...) with nothing to compare it to.如果你去掉 not in 你会得到一个错误,因为你的谓词只是变成sum(...)没有什么可以比较的。

Looks like you can clean up your having clause a little bit.看起来你可以稍微清理一下你的having clause Doing so might make the role of not in more obvious这样做可能会使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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM