我有一张入住表和一份付费历史表。我想从相关薪酬时的入住状态返回员工所在的州。
占用表
Emp#|Commence Date|State
-----|-------------|----
101 | 1/01/2016 | VIC
101 | 1/04/2016 | NSW
101 | 1/08/2016 | ACT
付款历史表
Emp#|Pay Date
----|--------
101 |15/01/2016
101 |15/02/2016
101 |15/03/2016
101 |15/04/2016
101 |15/05/2016
101 |15/06/2016
101 |15/07/2016
101 |15/08/2016
101 |15/09/2016
我想要返回以下内容
Emp#|:Pay Date:|State
----|----------|-----
101 |15/01/2016|VIC
101 |15/02/2016|VIC
101 |15/03/2016|VIC
101 |15/04/2016|NSW
101 |15/05/2016|NSW
101 |15/06/2016|NSW
101 |15/07/2016|NSW
101 |15/08/2016|ACT
101 |15/09/2016|ACT
请有人协助,
答案 0 :(得分:1)
您需要在子查询中的end_date
表中生成occupancy
; lead()
函数非常适合此目的。我将它与所有三个参数一起使用 - 第三个参数给出一个"默认"我在2099年12月15日为当前"任意选择的日期。状态。然后是empno
上的简单联接和日期上的between
条件。
我假设您的数据中有多个empno
,所以我接受了。然后:我不知道#在Oracle列名中是否合法,但我不想尝试;我改为empno
。除非你引用名称,否则名称肯定不能有空格,这有很多缺点;我也在努力。
with
occupancy ( empno, commence_date, state ) as (
select 101, to_date('1/01/2016', 'dd/mm/yyyy'), 'VIC' from dual union all
select 101, to_date('1/04/2016', 'dd/mm/yyyy'), 'NSW' from dual union all
select 101, to_date('1/08/2016', 'dd/mm/yyyy'), 'ACT' from dual
),
pay_history ( empno, pay_date ) as (
select 101, to_date('15/01/2016', 'dd/mm/yyyy') from dual union all
select 101, to_date('15/02/2016', 'dd/mm/yyyy') from dual union all
select 101, to_date('15/03/2016', 'dd/mm/yyyy') from dual union all
select 101, to_date('15/04/2016', 'dd/mm/yyyy') from dual union all
select 101, to_date('15/05/2016', 'dd/mm/yyyy') from dual union all
select 101, to_date('15/06/2016', 'dd/mm/yyyy') from dual union all
select 101, to_date('15/07/2016', 'dd/mm/yyyy') from dual union all
select 101, to_date('15/08/2016', 'dd/mm/yyyy') from dual union all
select 101, to_date('15/09/2016', 'dd/mm/yyyy') from dual
)
-- end of test data (not part of the SQL query); query begins below this line
select p.empno, p.pay_date, o.state
from pay_history p inner join (
select empno, commence_date,
lead(commence_date, 1, date '2099-12-15')
over (partition by empno order by commence_date) as end_date,
state
from occupancy ) o
on p.empno = o.empno
and p.pay_date between o.commence_date and o.end_date
order by empno, pay_date -- if needed
;
<强>输出强>:
EMPNO PAY_DATE STATE
----- ---------- -----
101 15/01/2016 VIC
101 15/02/2016 VIC
101 15/03/2016 VIC
101 15/04/2016 NSW
101 15/05/2016 NSW
101 15/06/2016 NSW
101 15/07/2016 NSW
101 15/08/2016 ACT
101 15/09/2016 ACT
9 rows selected.
答案 1 :(得分:0)
在这里谈判自己:-)我将此作为单独的答案发布,而不是编辑我之前的答案,因为这确实是一个不同的答案。
请参阅我的其他答案,了解输入数据和样本输出 - 它们是相同的。只有查询不同。我们可以UNION ALL两个表而不是连接,而是进行一些必要的调整:将null
列state
添加到pay_history
表,flag
{对于0
表{1}}和occupancy
表的1
;然后在生成的union上使用pay_history
解析函数,并从最外层查询中的last_value()
表中过滤掉行。这可能比基于连接的解决方案快得多。
occupancy