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日)、annualDateEndは2014-04-30になります。2013年5月1日が来るまで2013年4月30日のままにしておきたいのですが、 2014-04-30になります(半年ごとの同様の状況)。

これらの日付を特定のパイロットに静的に関連付けたままにしたくありません。つまり、これらを含むパイロットテーブルにいくつかのフィールドを保持したくありません。ただし、これらを表示と計算に使用したいと思います。たとえば、各パイロットの現在の半年ごとおよび年次の出撃と飛行時間を表示する必要があります。また、特定の時点での「現在の」統計のスナップショットを表示する必要があります。

編集:SQL Server 2008ExpressRCを使用しています

編集2:@currentBirthDateを(SELECT DATEADD(yyyy、@diffInYears --1、@date)に変更する必要があると考えています。次に、以下のcaseステートメントを実行する必要があります(実験を続ける)

4

2 に答える 2

1

半年ごとの日付の規則は次のようです。月に 5 か月を追加し、月末に移動します。月末が問題かもしれません。では、これを「6 か月足して、月末になってから 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

This ended up working... Problem is, I'm going to need to do this for every pilot on the overall summary page. Additionally, I'm going to need to calculate this kind of sortie information for snapshots that she wants. She wants to go back to any particular month and see a snapshot, listing each flight as well as the sortie stats they had upon completing that flight. This SQL should work for these situations, it's just I'll have to change it up a bit here and there.

(EDIT: Why doesn't my code scroll horizontally..? I don't want it to wrap. Nevermind that's just internet explorer looks like)

于 2012-07-22T19:20:30.020 に答える