我需要使用两个参数构建一个表值用户定义函数
输入如select * from func_1('01/01/2012','09/09/2015');
输出应该是:
month quator semi_annual annual
1 1 1 2012
2 1 1 2012
3 1 1 2012
4 2 1 2012
5 2 1 2012
6 2 1 2012
7 3 2 2012
. . . ...
. . . ....
upto
9 3 2 2015
我需要一个表值函数。
我试过这样的代码
create function func3_D_D
(@startDate date, @endDate date)
RETURNS @dates table
(months int,quatorly int,Semi_anuual int,Annual int)
As
Begin
declare
@months int,
@quatorly int,
@Semi_anuual int,
@Annual int;
select @months= DATEDIFF(MONTH, @startDate, @endDate);
select @quatorly= DATEDIFF(QUARTER, @startDate, @endDate);
select @Semi_anuual= DATEDIFF(QUARTER, @startDate, @endDate)/ 2;
select @Annual= DATEDIFF(YEAR, @startDate, @endDate);
WHILE (@endDate > @startDate)
begin
insert into @dates
select @months,@quatorly,@Semi_anuual,@Annual;
End;
return;
End;
答案 0 :(得分:0)
使用循环可以获得很好的性能。你需要为这种类型的东西使用计数表。你需要开始思考而不是逐行思考。一旦你有一个计数表(我在这里用cte生成),这很简单。
create function MyFunctionThatGetsDatesByRange
(
@StartDate DATE
, @EndDate DATE
) RETURNS TABLE WITH SCHEMABINDING AS RETURN
WITH
E1(N) AS (select 1 from (values (1),(1),(1),(1),(1),(1),(1),(1),(1),(1))dt(n)),
E2(N) AS (SELECT 1 FROM E1 a, E1 b), --10E+2 or 100 rows
E4(N) AS (SELECT 1 FROM E2 a, E2 b), --10E+4 or 10,000 rows max
cteTally(N) AS
(
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E4
)
select DATEADD(DAY, N - 1, @StartDate) as date
, DATEPART(MONTH, DATEADD(DAY, N - 1, @StartDate)) as Month
, DATEPART(QUARTER, DATEADD(DAY, N - 1, @StartDate)) as Quarter
, CASE when DATEPART(QUARTER, DATEADD(DAY, N - 1, @StartDate)) <= 2 then 1 else 2 end as SemiAnnual
, DATEPART(YEAR, DATEADD(DAY, N - 1, @StartDate)) as Annual
from cteTally
where N <= DATEDIFF(DAY, @StartDate, @EndDate);
GO
declare @StartDate date = '2012-01-01'
, @EndDate date = '2015-09-09';
select *
from dbo.MyFunctionThatGetsDatesByRange(@StartDate, @EndDate)
答案 1 :(得分:0)
非常感谢您的回复,我通过使用以下代码获得了答案。
create function func5_D_D
(@startDate date, @endDate date)
RETURNS @dates table
(months int,
quators int,
semi_annual int,
annual int)
As
Begin
WHILE @startDate <= @endDate
BEGIN
INSERT INTO @dates(months,quators,semi_annual,annual) values (MONTH(@startDate), datepart(qq,@startDate),
case when datepart(qq,@startDate) in (1,2) then 1 else
2 End,datepart(yyyy,@startdate))
SET @startDate = DATEADD(MONTH,1,@startDate)
END
return;
end;
答案 2 :(得分:0)
X年Y个月和Z天中的两个日期之间的差异(例如:年,月和日中的年龄) 我们可以使用下面的脚本来获取年,月和日中两个日期之间的差。
X年Y个月和Z天中的两个日期之间的差异(例如:年,月和日中的年龄) 我们可以使用如下脚本来获取两个
之间的区别datDECLARE @FromDate DATETIME = '2010-01-01 23:59:59.000',
@ToDate DATETIME = '2015-01-02 00:00:00.000',
@Years INT, @Months INT, @Days INT, @tmpFromDate DATETIME
SET @Years = DATEDIFF(YEAR, @FromDate, @ToDate)
- (CASE WHEN DATEADD(YEAR, DATEDIFF(YEAR, @FromDate, @ToDate),
@FromDate) > @ToDate THEN 1 ELSE 0 END)
SET @tmpFromDate = DATEADD(YEAR, @Years , @FromDate)
SET @Months = DATEDIFF(MONTH, @tmpFromDate, @ToDate)
- (CASE WHEN DATEADD(MONTH,DATEDIFF(MONTH, @tmpFromDate, @ToDate),
@tmpFromDate) > @ToDate THEN 1 ELSE 0 END)
SET @tmpFromDate = DATEADD(MONTH, @Months , @tmpFromDate)
SET @Days = DATEDIFF(DAY, @tmpFromDate, @ToDate)
- (CASE WHEN DATEADD(DAY, DATEDIFF(DAY, @tmpFromDate, @ToDate),
@tmpFromDate) > @ToDate THEN 1 ELSE 0 END)
SELECT @FromDate FromDate, @ToDate ToDate,
@Years Years, @Months Months, @Days Days
s in Years, Months and days.