Table left join 自身返回 NULL
Table left join with itself returning NULL
我有一个table喜欢
Tdate Symbol new_close
20100110 xxx 1.2
20100111 xxx 1.3
...
20100110 yyy 1.1
20100111 yyy 1.5
其中 Tdate 存储为整数并每天为每个交易品种更新。我想通过将 new_close 值减去其前一个值来从中生成一个新的 table,看起来像这样
Tdate Symbol delta
20100110 xxx =1.2-1.2
20100111 xxx =1.3-1.2
...
20100110 yyy =1.1-1.1
20100111 yyy =1.5-1.1
这是我的代码
with delta as
( select a.Tdate as TDate, a.Symbol as Symbol,
a.new_close-b.new_close as Pdelta, b.new_close as oldPrice
from ctsWithSplit a left join ctsWithSplit b
on a.TDate-b.TDate=1 and a.Symbol=b.Symbol)
但是,在新生成的 table 中,某些增量值是 NULL,请问如何解决?
当您的左联接在 b
中找不到匹配的行时(即在第一个 Tdate
或前一天没有 Tdate
的地方) ,那么 b.new_close
将为 NULL,减法的结果也是如此。
尝试:
select
a.Tdate as TDate,
a.Symbol as Symbol,
CASE WHEN b.new_close IS NULL THEN 0 ELSE a.new_close-b.new_close END as Pdelta,
b.new_close as oldPrice
from ctsWithSplit a
left join ctsWithSplit b
on a.TDate-b.TDate=1
and a.Symbol=b.Symbol
为什么 TDATE
被存储为一个数字?如果日期是本月的第一天,您的查询将无法找到前一天 - 例如:20150201 - 20150131 = 70,而 1 月 31 日和 2 月 1 日之间只有一天。
将日期存储为 DATE
或 TIMESTAMP
数据类型,然后您让 Oracle 有机会获得正确的日期算法。
也许您正在寻找类似的东西:
with sample_data as (select to_date('10/01/2010', 'dd/mm/yyyy hh24:mi:ss') tdate, 'xxx' symbol, 1.2 new_close from dual union all
select to_date('11/01/2010', 'dd/mm/yyyy hh24:mi:ss') tdate, 'xxx' symbol, 1.3 new_close from dual union all
select to_date('10/01/2010', 'dd/mm/yyyy hh24:mi:ss') tdate, 'yyy' symbol, 1.1 new_close from dual union all
select to_date('11/01/2010', 'dd/mm/yyyy hh24:mi:ss') tdate, 'yyy' symbol, 1.5 new_close from dual)
select tdate,
symbol,
new_close - lag(new_close, 1, new_close) over (partition by symbol order by tdate) delta
from sample_data;
TDATE SYMBOL DELTA
---------- ------ -----
10/01/2010 xxx 0.0
11/01/2010 xxx 0.1
10/01/2010 yyy 0.0
11/01/2010 yyy 0.4
如果您从未使用过分析函数,那么我建议您查找它们 - 它们非常有用且非常强大。
N.B。如果您无法将 TDATE
列转换为 DATE
数据类型,则需要使用 to_date()
在您 运行 的任何查询中将该列转换为日期。
我有一个table喜欢
Tdate Symbol new_close
20100110 xxx 1.2
20100111 xxx 1.3
...
20100110 yyy 1.1
20100111 yyy 1.5
其中 Tdate 存储为整数并每天为每个交易品种更新。我想通过将 new_close 值减去其前一个值来从中生成一个新的 table,看起来像这样
Tdate Symbol delta
20100110 xxx =1.2-1.2
20100111 xxx =1.3-1.2
...
20100110 yyy =1.1-1.1
20100111 yyy =1.5-1.1
这是我的代码
with delta as
( select a.Tdate as TDate, a.Symbol as Symbol,
a.new_close-b.new_close as Pdelta, b.new_close as oldPrice
from ctsWithSplit a left join ctsWithSplit b
on a.TDate-b.TDate=1 and a.Symbol=b.Symbol)
但是,在新生成的 table 中,某些增量值是 NULL,请问如何解决?
当您的左联接在 b
中找不到匹配的行时(即在第一个 Tdate
或前一天没有 Tdate
的地方) ,那么 b.new_close
将为 NULL,减法的结果也是如此。
尝试:
select
a.Tdate as TDate,
a.Symbol as Symbol,
CASE WHEN b.new_close IS NULL THEN 0 ELSE a.new_close-b.new_close END as Pdelta,
b.new_close as oldPrice
from ctsWithSplit a
left join ctsWithSplit b
on a.TDate-b.TDate=1
and a.Symbol=b.Symbol
为什么 TDATE
被存储为一个数字?如果日期是本月的第一天,您的查询将无法找到前一天 - 例如:20150201 - 20150131 = 70,而 1 月 31 日和 2 月 1 日之间只有一天。
将日期存储为 DATE
或 TIMESTAMP
数据类型,然后您让 Oracle 有机会获得正确的日期算法。
也许您正在寻找类似的东西:
with sample_data as (select to_date('10/01/2010', 'dd/mm/yyyy hh24:mi:ss') tdate, 'xxx' symbol, 1.2 new_close from dual union all
select to_date('11/01/2010', 'dd/mm/yyyy hh24:mi:ss') tdate, 'xxx' symbol, 1.3 new_close from dual union all
select to_date('10/01/2010', 'dd/mm/yyyy hh24:mi:ss') tdate, 'yyy' symbol, 1.1 new_close from dual union all
select to_date('11/01/2010', 'dd/mm/yyyy hh24:mi:ss') tdate, 'yyy' symbol, 1.5 new_close from dual)
select tdate,
symbol,
new_close - lag(new_close, 1, new_close) over (partition by symbol order by tdate) delta
from sample_data;
TDATE SYMBOL DELTA
---------- ------ -----
10/01/2010 xxx 0.0
11/01/2010 xxx 0.1
10/01/2010 yyy 0.0
11/01/2010 yyy 0.4
如果您从未使用过分析函数,那么我建议您查找它们 - 它们非常有用且非常强大。
N.B。如果您无法将 TDATE
列转换为 DATE
数据类型,则需要使用 to_date()
在您 运行 的任何查询中将该列转换为日期。