我基本上有3个不同的select语句,它们根据键检索不同的行数。我想做减法,这样就不会丢掉任何记录。即使2个select语句返回null,我仍然会通过将它们设置为0来减去。
例如,
irb(main):001:0> require_relative 'lib/tracky'
LoadError: cannot load such file -- tracky/version
from /home/matheus/.rbenv/versions/2.2.2/lib/ruby/2.2.0/rubygems/core_ext/kernel_require.rb:54:in `require'
from /home/matheus/.rbenv/versions/2.2.2/lib/ruby/2.2.0/rubygems/core_ext/kernel_require.rb:54:in `require'
from /home/matheus/Ruby/tracky/lib/tracky.rb:1:in `<top (required)>'
from (irb):1:in `require_relative'
from (irb):1
from /home/matheus/.rbenv/versions/2.2.2/bin/irb:11:in `<main>'
在上面的例子中,我看到的是,由于WHERE子句条件,最终结果只返回5个记录的较小子集。我如何能够检索所有10个记录而不是较小的子集。理想情况下,我想要的是10条记录,其中那些匹配由(+, - )评估的WHERE CLAUSE和那些不匹配的记录也被设置为0进行评估。如果C得到记录而A,B没有,那么它将是c.exp_val +(0-0),A,B被设置为0.
答案 0 :(得分:3)
您可以使用full outer join
:
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);
如果您知道第三个子查询的行数最多,则可以重新排列子查询并使用LEFT JOIN
。
此外,永远不要在FROM
子句中使用逗号。始终使用明确的JOIN
。
另请注意,不匹配表格中的值为NULL
,而非0
。如果您需要0
,请使用COALESCE()
。
答案 1 :(得分:2)
正如戈登已经表明的那样,你通过使用全外连接获得所有记录。要使其可读,请使用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添加到USING子句using(key,col1)
。它不会改变任何东西并且是多余的,但您可能认为它更具可读性。添加或离开它,这取决于你。