我正在开发一个sql oracle数据库。我有一张带有id,begindate和enddate的表。
例如:
employee | begindate | enddate
john | 18/02/2015 | 18/02/2015
john | 19/02/2015 | 21/02/2015
我想对该表执行select语句,但是当begindate不等于enddate时,它必须添加一些行。在上面的示例中,第一行将保持这样,但第二行必须在三行中展开。 select语句的结果必须是:
john | 18/02/2015 | 18/02/2015
john | 19/02/2015 | 19/02/2015
john | 20/02/2015 | 20/02/2015
john | 21/02/2015 | 21/02/2015
所以我的select语句在这个例子中总共有4行。
有人知道我该怎么做吗?
答案 0 :(得分:3)
Oracle安装程序:
CREATE TABLE employees ( employee, begindate, enddate ) AS
SELECT 'john', DATE '2015-02-18', DATE '2015-02-18' FROM DUAL UNION ALL
SELECT 'john', DATE '2015-02-19', DATE '2015-02-21' FROM DUAL;
<强>查询强>:
SELECT e.employee,
t.COLUMN_VALUE AS begindate,
t.COLUMN_VALUE AS enddate
FROM employees e,
TABLE(
CAST(
MULTISET(
SELECT e.begindate + LEVEL - 1
FROM DUAL
CONNECT BY LEVEL <= e.enddate - e.begindate + 1
)
AS SYS.ODCIDATELIST
)
) t;
<强>结果:
EMPLOYEE BEGINDATE ENDDATE
-------- --------- ---------
john 18-FEB-15 18-FEB-15
john 19-FEB-15 19-FEB-15
john 20-FEB-15 20-FEB-15
john 21-FEB-15 21-FEB-15
答案 1 :(得分:1)
以下是直接在桌面上使用connect的替代答案:
with test as (select 'john' employee, to_date('18/02/2015', 'dd/mm/yyyy') begindate, to_date('18/02/2015', 'dd/mm/yyyy') enddate from dual union all
select 'john' employee, to_date('19/02/2015', 'dd/mm/yyyy') begindate, to_date('21/02/2015', 'dd/mm/yyyy') enddate from dual)
select employee,
begindate + level - 1 begindate,
begindate + level - 1 enddate
from test
connect by prior employee = employee
and prior begindate = begindate
and prior sys_guid() is not null
and begindate + level - 1 <= enddate;
EMPLOYEE BEGINDATE ENDDATE
-------- ---------- ----------
john 18/02/2015 18/02/2015
john 19/02/2015 19/02/2015
john 20/02/2015 20/02/2015
john 21/02/2015 21/02/2015
我建议您测试有效的答案,看看哪个答案对您的数据有最佳效果。
答案 2 :(得分:0)
解决方案与ORACLE SQL:Get all integers between two numbers非常相似,“两个数字”是begindate
和enddate
之间的日期范围。
类似的东西:
Create Table test (employee varchar(50), begindate date, enddate date);
Insert Into test (employee, begindate, enddate)
Values ('john', TO_DATE('18/02/2015', 'dd/mm/yyyy'), TO_DATE('18/02/2015', 'dd/mm/yyyy'));
Insert Into test (employee, begindate, enddate)
Values ('john', TO_DATE('19/02/2015', 'dd/mm/yyyy'), TO_DATE('21/02/2015', 'dd/mm/yyyy'));
然后
Select employee, enumdate As begindate, enumdate As enddate
From test Cross Apply (
Select begindate + rownum - 1 As enumdate
From Dual
Connect By Level <= enddate - begindate + 1
) enum;