Sql Oracle-根据不同来源的不同行数执行减法

Sql Oracle-根据不同来源的不同行数执行减法,sql,oracle,Sql,Oracle,我基本上有3个不同的select语句,它们根据一个键检索不同数量的行。我想做减法运算,这样就不会丢失任何记录。即使这两条select语句返回null,我仍然会通过将它们设置为0进行减法 比如说, SELECT COL1, COL2,COL3, (C.EXP_VAL + (A.EXP_VAL-B.EXP_VAL)) AS EXP_VAL FROM (SELECT * FROM A WHEN KEY = 1 AND CATE_TYPE=1) A, \\ RETURNS 5 ROWS (SELECT

我基本上有3个不同的select语句,它们根据一个键检索不同数量的行。我想做减法运算,这样就不会丢失任何记录。即使这两条select语句返回null,我仍然会通过将它们设置为0进行减法

比如说,

SELECT COL1, COL2,COL3, (C.EXP_VAL + (A.EXP_VAL-B.EXP_VAL)) AS EXP_VAL FROM 
(SELECT * FROM A WHEN KEY = 1 AND CATE_TYPE=1) A, \\ RETURNS 5 ROWS
(SELECT * FROM B WHERE KEY =1 AND CATE_TYPE=2) B, \\ RETURNS 5 ROWS
(SELECT * FROM C WHERE KEY=1 AND CATE_TYPE=3) C \\RETURNS 10 ROWS
WHERE A.KEY=B.KEY AND A.KEY=C.KEY AND A.COL1=B.COL1 AND A.COL1=C.COL1;

在上面的示例中,我看到的是,由于WHERE子句的条件,最终结果只返回5条记录中较小的子集。我如何能够检索所有10条记录,而不是较小的子集。理想情况下,我想要的是10条记录,匹配WHERE子句的记录由(+、-)计算,不匹配的记录也由设置为0计算。例如,如果C获得记录,而A、B没有,则将是C.exp_val+(0-0),其中A、B设置为0。

您可以使用
完全外部联接

SELECT COL1, COL2, COL3, (C.EXP_VAL + (A.EXP_VAL-B.EXP_VAL)) AS EXP_VAL
FROM (SELECT * FROM A WHEN KEY = 1 AND CATE_TYPE=1) A full outer join
     (SELECT * FROM B WHERE KEY =1 AND CATE_TYPE=2) B
     ON A.KEY = B.KEY AND
        A.COL1 = B.COL1 full outer join
     (SELECT * FROM C WHERE KEY=1 AND CATE_TYPE=3) C 
     ON C.KEY = COALESCE(A.KEY, B.KEY) AND
        C.COL1 = COALESCE(A.COL1, B.COL1);
如果知道第三个子查询的行数始终最多,则可以重新排列子查询,并使用
左联接

此外,切勿在
FROM
子句中使用逗号。始终使用显式
JOIN
s


还要注意,不匹配表中的值将是
NULL
,而不是
0
。如果您想要
0
,那么使用
COALESCE()

正如Gordon已经展示的那样,您可以通过使用完整的外部联接来获取所有记录。要使其可读,请使用USING子句,而不是ON:

select 
  col1, nvl(c.exp_val,0) + nvl(a.exp_val,0) - nvl(b.exp_val,0) as exp_val
from 
  (select * from a when key = 1 and cate_type = 1) a
full outer join 
  (select * from b when key = 1 and cate_type = 2) b using (col1)
full outer join 
  (select * from c when key = 1 and cate_type = 3) c using (col1);

链接所有记录的列显式地是Col1(因为它在USING子句中)加上隐式的Key(因为它在所有查询中都设置为相同的值)。如果愿意,可以使用(Key,col1)将键添加到USING子句
。它不会改变任何东西,而且是多余的,但是你可以认为它更可读。添加或保留,这取决于您。

可能需要使用带NVL功能的左连接。是否可以找到不存在c记录的a或b记录?如果是这样的话,你想不想在你的结果中看到它?谢谢戈登,谢谢你!感谢Thorsten的支持@托尔斯滕。这是个好主意。我忘记了
使用
修复了
完全外部联接
空值问题。