1

因此,飞行员必须在每 6 个月(半年)和每年(每年)内获得如此多的飞行时间和飞行架次。最大的痛苦是这些时期的开始和结束日期是基于他们的出生月份。

您可以在此处找到有关我的架构的更多信息:设计决策:部分日期的表架构以计算时间跨度 (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 日时,我希望 semiAnnualDateEnd 变为 2013-04-30。

另外,当 2013 年到来时(2013 年 1 月 1 日),每年的 DateEnd 将变为 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)。然后,我需要在下面做一个案例陈述(继续实验)

4

2 回答 2

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 天。

我认为类似的东西也适用于您的年份日期。

于 2012-07-23T01:20:32.827 回答
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 的样子)

于 2012-07-22T19:20:30.020 回答