因此,飞行员必须每6个月(半年)以及每年(每年)进行如此多的飞行时间和飞行飞行。最大的痛苦是这些时期的开始和结束日期都是基于他们的出生月份。
您可以在此处找到有关我的架构的更多信息:Design decision: Table schema for partial dates in order to calculate time spans (SQL Server)
DECLARE @date Date
SET @date = '1985-04-12'
DECLARE @diffInYears INT
SET @diffInYears = DATEDIFF(yy, @date, GETDATE())
DECLARE @currentBirthDate Date
SET @currentBirthDate = (SELECT dateadd(yyyy, @diffInYears, @date))
SELECT DATEADD(dd, -DAY(DATEADD(m,1,@currentBirthDate)), DATEADD(m,7,@currentBirthDate)) semiAnnualDateEnd,
DATEADD(dd, -DAY(DATEADD(m,1,@currentBirthDate)), DATEADD(m,13,@currentBirthDate)) annualDateEnd
RESULTS:
semiAnnualDateEnd - annualDateEnd
2012-10-31 - 2013-04-30
现在,这很好,这些是我想要这个特定例子的日期。
然而,当我们来到2012年11月1日时,我希望halfAnnualDateEnd成为2013-04-30。
此外,当2013年到来时(2013年1月1日),年度日期结束将成为2014-04-30,当我希望它保持2013-04-30直到2013-05-01到来,然后因为它成为2014-04-30(半年的类似情况)。
我不想让这些日期与特定飞行员保持静态关联。也就是说,我不想在Pilot表中保留一些具有这些字段的字段。但是,我想将它们用于显示和计算。例如,需要显示每个飞行员当前的半年和年度飞行时间,以及在任何特定时间点显示他们的“当前”统计数据的快照。
编辑:我正在使用SQL Server 2008 Express RC
编辑2:我想我应该将@currentBirthDate更改为(SELECT DATEADD(yyyy,@ diffInYears - 1,@ date)。然后,我需要在下面做一个案例陈述(继续实验)
答案 0 :(得分:1)
半年度日期的规则似乎是:在该月增加五个月并且到月底。月底可能是个问题。所以,让我们把它改为“增加六个月,到月底减去一天”。 (我将这个逻辑基于你的例子。)
以下表达式执行此操作:
select dateadd(d, -1,
cast(cast(year(bd)+(case when month(bd)+6 > 12 then 1 else 0 end) as varchar(255))+'-'+
cast(case when month(bd)+7> 12 then month(bd)+6-12 else month(bd) end as varchar(255))+'-'+
'1' as date))
from (select cast('2011-11-01' as date) bd) t
它对日期的year()和month()值进行日期算术运算。然后它将它们作为一个字符串重新组合在一起,转换为日期,并减去1天。
我认为类似的东西也适用于你的年份日期。
答案 1 :(得分:0)
DECLARE @pilotID INT
SET @pilotID = 1
DECLARE @birthDate DATE
SET @birthDate = (SELECT birthDate FROM Pilot WHERE pilotID = @pilotID)
DECLARE @diffInYears INT
SET @diffInYears = DATEDIFF(yy, @birthDate, GETDATE())
DECLARE @currentBirthDate DATE
SET @currentBirthDate = (DATEADD(yyyy, @diffInYears - 1, @birthDate))
DECLARE @firstSixMonthStart DATE
DECLARE @firstSixMonthEnd DATE
DECLARE @secondSixMonthStart DATE
DECLARE @secondSixMonthEnd DATE
SET @firstSixMonthStart = (DATEADD(dd,-(DAY(DATEADD(m,1,@currentBirthDate))-1),DATEADD(m,1,@currentBirthDate)))
SET @firstSixMonthEnd = (DATEADD(dd, -DAY(DATEADD(m,1,@currentBirthDate)), DATEADD(m,7,@currentBirthDate)))
SET @secondSixMonthStart = (DATEADD(dd,-(DAY(DATEADD(m,1,@currentBirthDate))-1),DATEADD(m,7,@currentBirthDate)))
SET @secondSixMonthEnd = (DATEADD(dd, -DAY(DATEADD(m,1,@currentBirthDate)), DATEADD(m,13,@currentBirthDate)))
DECLARE @semiAnnualStart AS DATE
DECLARE @semiAnnualEnd AS DATE
DECLARE @annualStart AS DATE
DECLARE @annualEnd AS DATE
SET @semiAnnualStart = CASE
WHEN GETDATE() > (DATEADD(dd, -DAY(DATEADD(m,1,@firstSixMonthEnd)), DATEADD(m,7,@firstSixMonthEnd)))
THEN (DATEADD(yyyy, 1, @firstSixMonthStart))
WHEN GETDATE() > @firstSixMonthEnd
THEN @secondSixMonthStart
ELSE @firstSixMonthStart
END
SET @semiAnnualEnd = CASE
WHEN GETDATE() > (DATEADD(dd, -DAY(DATEADD(m,1,@firstSixMonthEnd)), DATEADD(m,7,@firstSixMonthEnd)))
THEN (DATEADD(yyyy, 1, @firstSixMonthEnd))
WHEN GETDATE() > @firstSixMonthEnd
THEN @secondSixMonthEnd
ELSE @firstSixMonthEnd
END
SET @annualStart = CASE
WHEN GETDATE() > @secondSixMonthEnd THEN (DATEADD(yyyy, 1, @firstSixMonthStart))
ELSE @firstSixMonthStart
END
SET @annualEnd = CASE
WHEN GETDATE() > @secondSixMonthEnd THEN (DATEADD(yyyy, 1, @secondSixMonthEnd))
ELSE @secondSixMonthEnd
END
SELECT @semiAnnualStart semiStart, @semiAnnualEnd semiEnd,
@annualStart annualStart, @annualEnd annualEnd,
@firstSixMonthStart firstStart, @firstSixMonthEnd firstEnd,
@secondSixMonthStart secondStart, @secondSixMonthEnd secondEnd,
COUNT(*) semiSorties, ISNULL(SUM(hours), 0) semiSortieHours
FROM PilotLog
WHERE pilotID = @pilotID
AND topLevelPosition = 'AVO'
AND flightDate BETWEEN @semiAnnualStart AND @semiAnnualEnd
结果:
semiStart semiEnd annualStart annualEnd firstStart firstEnd secondStart secondEnd semiSorties semiSortieHours
2012-05-01 2012-10-31 2011-11-01 2012-10-31 2011-11-01 2012-04-30 2012-05-01 2012-10-31 1 1.7
这最终起作用了...问题是,我将需要为整个摘要页面上的每个飞行员执行此操作。另外,我将需要为她想要的快照计算这种出击信息。她希望回到任何特定的月份,看到快照,列出每个航班以及他们完成该航班时的出击统计数据。这个SQL应该适用于这些情况,我只需要在这里和那里稍微改变它。
(编辑:为什么我的代码不能横向滚动..?我不希望它包装。没关系,这只是Internet Explorer看起来像)