日期:2014-05-18  浏览次数:20473 次

根据两个‘年度参数’,如何获取到一个完整的年度序列字段
大家好,请教一个问题。
在MS SQL中,有两个参数,分别是【开始年度】,【截止年度】,如何获取一个完整的年度序列字段?
例如,【开始年度】为2000,【截止年度】为2005,则列字段如下:
年度
2000
2001
2002
2003
2004
2005

我猜测有两种方式可以实现,一种是通过存储过程,使用循环加1;另一种是直接写SQL。
但具体如何做,我没有思路,恳请大家,帮我看看,谢谢了。
(再补充一句,如果是在Oracle环境中,应该是可以通过相同的方法,予以实现,是吗?)


------解决方案--------------------
SQL code

declare @startyeay int
declare @endyear int
set @startyeay=2000
set @endyear=2005
select number as years from master..spt_values 
where type='P' and number between @startyeay and @endyear

/*
years
2000
2001
2002
2003
2004
2005
*/

Oracle不知道

------解决方案--------------------
SQL code

--生成连续日期的更多方法:
在实际生活中我们会遇到很多日期缺失的问题,但在统计的时候要求
显示出缺失的日期,面对这样的问题,我们如何实现?这里我把自己
学习的三种方法给大家分享一下:

方法一:创建存储过程实现

--如何用"最小缺失数"实现确实日期的自动补全
-->生成测试数据:
GO
IF OBJECT_ID('TBL')IS NOT NULL
DROP TABLE TBL
GO
CREATE TABLE TBL(
日期 DATE,
备注 VARCHAR(100)
)
GO
INSERT TBL
SELECT '2012-03-02','B' UNION ALL
SELECT '2012-03-05','C' UNION ALL
SELECT '2012-03-06','D' UNION ALL
SELECT '2012-03-07','E' UNION ALL
SELECT '2012-03-09','F' UNION ALL
SELECT '2012-03-11','G' UNION ALL
SELECT '2012-03-12','H' UNION ALL
SELECT '2012-03-13','I' UNION ALL
SELECT '2012-03-15','J' UNION ALL
SELECT '2012-03-19','K' UNION ALL
SELECT '2012-03-20','L'


GO
IF OBJECT_ID('P_SP')IS NOT NULL
DROP PROC P_SP
GO
CREATE PROC P_SP @ENDTIME DATE
AS
DECLARE @SQL VARCHAR(100)
SET @SQL='SELECT * FROM TBL ORDER BY 日期'
DECLARE @MINMISS DATE
SET @MINMISS=(
SELECT COALESCE(DATEADD(DD,1,MIN(A.日期)),
'2012-03-01') AS MISSING
FROM TBL A
WHERE NOT EXISTS(
SELECT * FROM TBL B 
WHERE B.日期=DATEADD(DD,1,A.日期))
AND EXISTS (
SELECT 1 FROM TBL WHERE 日期='2012-03-01'))
PRINT @MINMISS
WHILE @MINMISS<=@ENDTIME
BEGIN
INSERT TBL(日期) VALUES(@MINMISS)
SELECT @MINMISS=(
SELECT DATEADD(DD,1,MIN(A.日期))
FROM TBL A
WHERE NOT EXISTS(
SELECT * FROM TBL B 
WHERE B.日期=DATEADD(DD,1,A.日期))
)
END
EXEC(@SQL)

EXEC P_SP '2012-03-20'

/*
日期    备注
2012-03-01    NULL
2012-03-02    B
2012-03-03    NULL
2012-03-04    NULL
2012-03-05    C
2012-03-06    D
2012-03-07    E
2012-03-08    NULL
2012-03-09    F
2012-03-10    NULL
2012-03-11    G
2012-03-12    H
2012-03-13    I
2012-03-14    NULL
2012-03-15    J
2012-03-16    NULL
2012-03-17    NULL
2012-03-18    NULL
2012-03-19    K
2012-03-20    L

*/


--------------------------------------------------
--------------------------------------------------
--方法二,利用递归实现:
-->生成测试数据:
GO
IF OBJECT_ID('TBL')IS NOT NULL
DROP TABLE TBL
GO
CREATE TABLE TBL(
日期 DATE
)
GO
INSERT TBL
SELECT '2012-03-01' UNION ALL
SELECT '2012-03-31'


--利用递归实现输出三月份的所有日期:
go
declare @date date
select @date=MAX(日期) from tbl
;with t
as(
select * from tbl
union all
select dateadd(dd,1,a.日期) from t a
where not exists(select * from tbl b
where b.日期=DATEADD(DD,1,a.日期)
)
and a.日期<@date
)
select *from t order by 日期

/*
日期
2012-03-01
2012-03-02
2012-03-03
2012-03-04
2012-03-05
2012-03-06
2012-03-07
2012-03-08
2012-03-09
2012-03-10
2012-03-11
2012-03-12
2012-03-13
2012-03-14
2012-03-15
2012-03-16
2012-03-17
2012-03-18
2012-03-19
2012-03-20
2012-03-21
2012-03-22
2012-03-23
2012-03-24
2012-03-25
2012-03-26
2012-03-27
2012-03-28
2012-03-29
2012-03-30
2012-03-31
*/

---------------------------------------------------
---------------------------------------------------
方法三:利用系统表构造实现
/*
    create table #tB(
    [A] int,
    [C2] varchar(10),
    [C3] datetime
    ) 
    insert #tB 
    select 1,'dfgsdfgsdf','2010-02-01' union all 
    select 2,'dfgsdfgsdf','2010-02-02' union all 
    select 3,'dfgsdfgsdf','2010-02-03' union all 
    select 4,'dfgsdfgsdf','2010-02-04' union all 
    select 4,'dfgsdfgsdf','2010-09-04' union all 
    select 5,'dfgsdfgsdf','2010-09-08' union all 
    select 5,'dfgsdfgsdf','2010-03-08' union all 
    select 6,'dfgsdfgsdf','2010-03-11' union all 
    select 4,'dfgsdfgsdf','2010-05-04' union all