我有两张桌子:
table1
user start end parameter
1 1 jan 2010 31 mar 2010 abc
1 1 apr 2010 30 jun 2010 abc
1 1 jan 2010 31 mar 2010 xyz
1 1 apr 2010 30 jun 2010 xyz
1 1 jan 2010 31 mar 2010 qqq
1 1 apr 2010 30 jun 2010 qqq
table2
start end parameter value
1 jan 2009 31 mar 2009 abc 100
1 apr 2009 30 jun 2009 abc 200
1 jan 2009 31 mar 2009 xyz 300
1 apr 2009 30 jun 2009 xyz 400
1 jan 2009 31 mar 2009 qqq 500
1 apr 2009 30 jun 2009 qqq 600
我必须根据参数,开始和结束关联2个表。我需要找到最近的值。所以,对于前者。 2010年1月1日 - 2010年3月31日对于参数abc,我们在table2中没有任何值,因此得到最接近的值,即2009年4月1日至2009年3月30日,参数abc和关联值200.另外,找出天数的差异从两个表开始。
结果表应如下所示:
表3:
user start end parameter value diff
1 1 jan 2010 31 mar 2010 abc 200 270 days
1 1 apr 2010 30 jun 2010 abc 200 365 days
1 1 jan 2010 31 mar 2010 xyz 400 270 days
1 1 apr 2010 30 jun 2010 xyz 400 365 days
1 1 jan 2010 31 mar 2010 qqq 600 270 days
1 1 apr 2010 30 jun 2010 qqq 600 365 days
答案 0 :(得分:2)
这是一种方式:
with table1 as (select 1 usr, to_date('01/01/2010', 'dd/mm/yyyy') start_date, to_date('31/03/2010', 'dd/mm/yyyy') end_date, 'abc' parameter from dual union all
select 1 usr, to_date('01/04/2010', 'dd/mm/yyyy') start_date, to_date('30/06/2010', 'dd/mm/yyyy') end_date, 'abc' parameter from dual union all
select 1 usr, to_date('01/01/2010', 'dd/mm/yyyy') start_date, to_date('31/03/2010', 'dd/mm/yyyy') end_date, 'xyz' parameter from dual union all
select 1 usr, to_date('01/04/2010', 'dd/mm/yyyy') start_date, to_date('30/06/2010', 'dd/mm/yyyy') end_date, 'xyz' parameter from dual union all
select 1 usr, to_date('01/01/2010', 'dd/mm/yyyy') start_date, to_date('31/03/2010', 'dd/mm/yyyy') end_date, 'qqq' parameter from dual union all
select 1 usr, to_date('01/04/2010', 'dd/mm/yyyy') start_date, to_date('30/06/2010', 'dd/mm/yyyy') end_date, 'qqq' parameter from dual),
table2 as (select 1 usr, to_date('01/01/2009', 'dd/mm/yyyy') start_date, to_date('31/03/2009', 'dd/mm/yyyy') end_date, 'abc' parameter, 100 value from dual union all
select 1 usr, to_date('01/04/2009', 'dd/mm/yyyy') start_date, to_date('30/06/2009', 'dd/mm/yyyy') end_date, 'abc' parameter, 200 value from dual union all
select 1 usr, to_date('01/01/2009', 'dd/mm/yyyy') start_date, to_date('31/03/2009', 'dd/mm/yyyy') end_date, 'xyz' parameter, 300 value from dual union all
select 1 usr, to_date('01/04/2009', 'dd/mm/yyyy') start_date, to_date('30/06/2009', 'dd/mm/yyyy') end_date, 'xyz' parameter, 400 value from dual union all
select 1 usr, to_date('01/01/2009', 'dd/mm/yyyy') start_date, to_date('31/03/2009', 'dd/mm/yyyy') end_date, 'qqq' parameter, 500 value from dual union all
select 1 usr, to_date('01/04/2009', 'dd/mm/yyyy') start_date, to_date('30/06/2009', 'dd/mm/yyyy') end_date, 'qqq' parameter, 600 value from dual)
-- end of mimicking your tables; see SQL below:
select usr,
start_date,
end_date,
parameter,
latest_value,
diff_days
from (select usr,
start_date,
end_date,
parameter,
last_value(value ignore nulls) over (partition by usr, parameter order by start_date) latest_value,
start_date - last_value(case when value is not null then start_date end ignore nulls) over (partition by usr, parameter order by start_date) diff_days
from (select usr,
start_date,
end_date,
parameter,
cast(null as number) value
from table1
union all
select usr,
start_date,
end_date,
parameter,
value
from table2))
where diff_days > 0;
USR START_DATE END_DATE PARAMETER LATEST_VALUE DIFF_DAYS
---------- ----------- ----------- --------- ------------ ----------
1 01 jan 2010 31 mar 2010 abc 200 275
1 01 apr 2010 30 jun 2010 abc 200 365
1 01 jan 2010 31 mar 2010 qqq 600 275
1 01 apr 2010 30 jun 2010 qqq 600 365
1 01 jan 2010 31 mar 2010 xyz 400 275
1 01 apr 2010 30 jun 2010 xyz 400 365
这使用分析函数last_value()
来查找值的最新非空值及其对应的end_date,然后进行必要的减法以获得后期和最新可用期间的开始之间的差异日期。
N.B。这假设两个表之间没有重叠的句点。