当我执行此查询时,我得到 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
我有一个名为 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