当我执行此查询时,我得到 NULL 值。为什么?

When I'm doing this query I'm getting NULL values. Why?

我有一个名为 fact_trip 的 table,其中有一列为 fare_final,我想找出值之间的差异。

SQL> desc fact_trip
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 TRIP_UUID                                 NOT NULL VARCHAR2(20)
 DATESTR                                            DATE
 PRODUCT_TYPE_NAME                                  VARCHAR2(20)
 CITY_ID                                            NUMBER
 DRIVER_UUID                                        VARCHAR2(50)
 IS_COMPLETED                                       VARCHAR2(10)
 ETA                                                NUMBER
 ATA                                                NUMBER
 UFP_FARE                                           NUMBER(4,2)
 FARE_FINAL                                         NUMBER(4,2)

所以当我这样做时,我得到 NULL 作为输出:

SQL>  select sum(fare_final) from fact_trip where to_char(datestr, 'W')=1 - (select sum(fare_final) from fact_trip where to_char(datestr, 'W')=2);

SUM(FARE_FINAL)
---------------

我什至尝试像这样单独执行那些 select 查询:

SQL> select sum(fare_final) from fact_trip where to_char(datestr, 'W')=1;

SUM(FARE_FINAL)
---------------
         1821.6

SQL> select sum(fare_final) from fact_trip where to_char(datestr, 'W')=2;

SUM(FARE_FINAL)
---------------
             67

这当然是抓取结果。但是当我 运行 那些查询我想要的不同时,它显示 NULL。就像我想要它们的区别 (1821.6 - 67)。 任何人都可以告诉它有什么问题吗? 谢谢!

应该是

SELECT SUM (
          CASE
             WHEN TO_CHAR (datestr, 'W') = 1 THEN  fare_final
             WHEN TO_CHAR (datestr, 'W') = 2 THEN -fare_final
          END)
  FROM fact_trip;

我没有你的 table,所以我将在 Scott 的 EMP 上进行说明,计算分析师和职员的 总数

SQL>   SELECT job, sal FROM emp ORDER BY job;

JOB              SAL
--------- ----------
ANALYST         3000  --> total for analysts is 6000
ANALYST         3000
CLERK           1300  --> total for clerks   is 4150
CLERK            950
CLERK            800  --> difference: 6000 - 4150 = 1850
CLERK           1100
MANAGER         2850
MANAGER         2975
MANAGER         2450
PRESIDENT       5000
SALESMAN        1500
SALESMAN        1250
SALESMAN        1250
SALESMAN        1600

14 rows selected.

SQL> SELECT SUM (
  2            CASE WHEN job = 'ANALYST' THEN  sal
  3                 WHEN job = 'CLERK'   THEN -sal
  4            END) total
  5    FROM emp;

     TOTAL
----------
      1850

SQL>

SQL 不是工作表,您可以在其中计算任何表达式。您不能将 expression 用作 SQL 命令:您必须 select 一个表达式 from 某些东西,或者在 PL/SQL 块中计算它。

您想计算​​差值,所以您假设您的代码是:subquery - subquery。但是由于上述原因,这不是语法正确的命令,解析器会尝试找到语法正确的解析树。它实际上找到了一个:

select sum(fare_final)
from fact_trip
where to_char(datestr, 'W') = (
  1 - (
    select sum(fare_final)
    from fact_trip
    where to_char(datestr, 'W') = 2
  )
)

当然,这样的一周是不存在的,结果你得到null

要将您的代码转换为正确的命令,最简单的方法是 select 来自 dual table 的 表达式 用于指定计算优先级的括号:

select
  (select sum(fare_final) from fact_trip where to_char(datestr, 'W')='1')
  - (select sum(fare_final) from fact_trip where to_char(datestr, 'W')='2') as res
from dual

但性能更高且基于集合的方法是:

select
  sum(
    case to_char(datestr, 'W')
      when '1' then 1
      when '2' then -1
    end * fare_final
  ) as res
from fact_trip
where to_char(datestr, 'W') in ('1', '2')

下面是包含上述所有结果的示例代码:

select * from t
ID | VAL
-: | --:
 1 |   3
 2 |   6
 3 |   9
select sum(val)
from t
where id = 1 - (
  select sum(val)
  from t
  where id = 2
)
| SUM(VAL) |
| -------: |
|     null |
select
  (
(select sum(val)
from t
where id = 1) - (
  select sum(val)
  from t
  where id = 2
)
  ) as q
from dual
|  Q |
| -: |
| -3 |
select
  sum(
    case id
     when 1 then 1
     when 2 then -1
    end * val
  ) as res
from t
where id in (1, 2)
| RES |
| --: |
|  -3 |

db<>fiddle here