两个日期之间的年份列表

时间:2014-09-30 08:13:32

标签: sql oracle

我有一个包含开始和结束列的表。 我的目标是在每个时间段内获取每行的列表,所以

+-------------------------+
| startdate  | enddate    |
+------------+------------+
| 2004-08-01 | 2007-01-08 |
| 2005-06-02 | 2007-05-08 |
+------------+------------+

应输出:

+-------+
| years |
+-------+
| 2004  |
| 2005  |
| 2006  |
| 2007  |
| 2005  |
| 2006  |
| 2007  |
+-------+

我现在有问题要在两个日期之间创造岁月。我的第一种方法是使用UNION(日期顺序无关紧要),但在这种情况下,中间的年份缺失......

Select
  Extract(Year From startdate)
From
  table1
Union
Select
  Extract(Year From enddate)
From
  table1

感谢您的任何建议!

3 个答案:

答案 0 :(得分:3)

行生成器技术

SQL> WITH DATA1 AS(
  2  SELECT TO_DATE('2004-08-01','YYYY-MM-DD') STARTDATE, TO_DATE('2007-01-08','YYYY-MM-DD') ENDDATE FROM DUAL UNION ALL
  3  SELECT TO_DATE('2005-06-02','YYYY-MM-DD') STARTDATE, TO_DATE('2007-05-08','YYYY-MM-DD') ENDDATE FROM DUAL
  4  ),
  5  DATA2 AS(
  6  SELECT EXTRACT(YEAR FROM STARTDATE) ST, EXTRACT(YEAR FROM ENDDATE) ED FROM DATA1
  7  ),
  8  data3
  9  AS
 10    (SELECT level-1 line
 11    FROM DUAL
 12      CONNECT BY level <=
 13      (SELECT MAX(ed-st) FROM data2
 14      )
 15    )
 16  SELECT ST+LINE FROM
 17  DATA2, DATA3
 18  WHERE LINE <= ED-ST
 19  ORDER BY 1
 20  /

   ST+LINE
----------
      2004
      2005
      2005
      2006
      2006
      2007

6 rows selected.

SQL>

答案 1 :(得分:2)

尝试此查询

; with  CTE as
        (
        select  datepart(year, '2005-12-25') as yr
        union all
        select  yr + 1
        from    CTE
        where   yr < datepart(year, '2013-11-14')
        )
select  yr
from    CTE

答案 2 :(得分:0)

试试这个:

创建一个包含以下年份的表格:

CREATE TABLE tblyears(y int)

INSERT INTO tblyears VALUES (1900);
INSERT INTO tblyears VALUES (1901);
INSERT INTO tblyears VALUES (1902);

等等,直到

INSERT INTO tblyears VALUES (2100)

因此,您将编写此查询:

SELECT y.y
FROM tblyears y
JOIN table1 t
ON y.y >= EXTRACT(year from startdate)
AND y.y <= EXTRACT(year from enddate)
ORDER BY y.y

Show SqlFiddle