返回基于数据的相关日期

时间:2017-01-18 06:00:59

标签: sql oracle date

我有一张入住表和一份付费历史表。我想从相关薪酬时的入住状态返回员工所在的州。

占用表

 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

请有人协助,

2 个答案:

答案 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两个表而不是连接,而是进行一些必要的调整:将nullstate添加到pay_history表,flag {对于0表{1}}和occupancy表的1;然后在生成的union上使用pay_history解析函数,并从最外层查询中的last_value()表中过滤掉行。这可能比基于连接的解决方案快得多。

occupancy