0

この質問は、ここの質問の延長です

私はデーンの答えを拡張しようとしましたが、結果は少し問題があります.

DECLARE @dateFrom DATETIME
DECLARE @dateTo DATETIME
DECLARE @tmpdate DATETIME 
DECLARE @years INT
DECLARE @months INT
DECLARE @days INT
DECLARE @hours INT
DECLARE @minutes INT
DECLARE @seconds INT
DECLARE @milliseconds INT

SELECT @dateFrom = '2011-01-01 11:24:38:100'
SELECT @dateTo = '2012-01-01 11:24:38:110'

SELECT @tmpdate = @dateFrom

SELECT @years = DATEDIFF(yy, @tmpdate, @dateTo) 
        - CASE WHEN (MONTH(@dateFrom) > MONTH(@dateTo)) OR (MONTH(@dateFrom) =  MONTH(@dateTo) AND DAY(@dateFrom) > DAY(@dateTo))
            THEN 1
            ELSE 0
        END
SELECT @tmpdate         = DATEADD(yy, @years, @tmpdate)
SELECT @months          = DATEDIFF(mm, @tmpdate, @dateTo) - CASE WHEN   DAY(@dateFrom) > DAY(@dateTo) THEN 1 ELSE 0 END
SELECT @tmpdate         = DATEADD(mm, @months, @tmpdate)
SELECT @days            = DATEDIFF(dd, @tmpdate, @dateTo)
SELECT @tmpdate         = DATEADD(dd, @days, @tmpdate)
SELECT @hours           = DATEDIFF(hh, @tmpdate, @dateTo)
SELECT @tmpdate         = DATEADD(hh, @hours, @tmpdate)
SELECT @minutes         = DATEDIFF(mi, @tmpdate, @dateTo)
SELECT @tmpdate         = DATEADD(mi, @minutes, @tmpdate)
SELECT @seconds         = DATEDIFF(ss, @tmpdate, @dateTo)
SELECT @tmpdate         = DATEADD(ss, @seconds, @tmpdate)
SELECT @milliseconds    = DATEDIFF(ms, @tmpdate, @dateTo)

SELECT
    @years AS [years]
    , @months AS [months]
    , @days AS [days]
    , @hours AS [hours]
    , @minutes AS [minutes]
    , @seconds AS [seconds]
    , @milliseconds AS [milliseconds]

結果は次のとおりです。

years   months  days    hours   minutes seconds milliseconds
1       0       0       0       0       0       10

しかし、私が実行すると:

SELECT @dateFrom = '2011-01-02 11:24:38:110'
SELECT @dateTo = '2012-01-01 10:23:37:100'

結果は次のとおりです。

years   months  days    hours   minutes seconds milliseconds
0       11      30      -1      -1      -1      -10

助けていただければ幸いです!

4

5 に答える 5

2

@dateFrom の日付が @dateTo の日付よりも遅いため、これらの負の値が得られます。これが発生したときにプロセスが開始される前にこれらの値を交換するのが最善だと思います。その後、変数を再フォーマットする必要はありません。プロセス:

DECLARE @auxDate DATETIME

IF (@dateFrom>@dateTo) 
BEGIN
     SET @auxDate = @dateFrom
     SET @dateFrom = @dateTo
     SET @dateTo = @auxDate
END

     -- Your code..
于 2012-06-25T07:41:04.953 に答える
2

答えは正しいですが、負の値で表示されます。正の値を返すには abs を使用する必要があります

 SELECT
 @years AS [years]
, abs(@months) AS [months]
, abs(@days) AS [days]
, abs(@hours) AS [hours]
, abs(@minutes) AS [minutes]
, abs(@seconds) AS [seconds]
, abs(@milliseconds) AS [milliseconds]
于 2012-06-25T07:11:49.787 に答える
0

ここで回答された私の質問を見てください。
次のようなケースを扱います。

@dateFrom = '2014-04-24 13:59:00'
@dateTo = '2014-04-24 14:01:00'

コードは、これらの値に対して間違った日付を返します。

于 2014-04-24T11:26:44.497 に答える
0
DECLARE @dateFrom DATETIME
DECLARE @dateTo DATETIME
DECLARE @tmpdate DATETIME 
DECLARE @years INT
DECLARE @months INT
DECLARE @days INT
DECLARE @hours INT
DECLARE @minutes INT
DECLARE @seconds INT
DECLARE @milliseconds INT
DECLARE @sign CHAR

--SELECT @dateFrom = '2011-01-01 11:24:38:100'
--SELECT @dateTo = '2012-01-01 11:24:38:110'

SELECT @dateFrom    = '2012-02-03 11:24:38:000'
SELECT @dateTo      = '2013-03-04 12:25:39:003'
SELECT @sign        = '+'

IF @dateFrom > @dateTo
BEGIN
    SET @tmpdate = @dateFrom
    SET @dateFrom = @dateTo
    SET @dateTo = @tmpdate
    SET @sign = '-'
END

SELECT @tmpdate = @dateFrom

SELECT @years           = DATEDIFF(yy, @tmpdate, @dateTo) 
                            - CASE WHEN
                                   (DATEPART(mm, @dateFrom) > DATEPART(mm, @dateTo)) 
                                OR (DATEPART(mm, @dateFrom) = DATEPART(mm, @dateTo) AND DATEPART(dd, @dateFrom) > DATEPART(dd, @dateTo))
                                OR (DATEPART(dd, @dateFrom) = DATEPART(dd, @dateTo) AND DATEPART(hh, @dateFrom) > DATEPART(hh, @dateTo))
                                OR (DATEPART(hh, @dateFrom) = DATEPART(hh, @dateTo) AND DATEPART(mi, @dateFrom) > DATEPART(mi, @dateTo))
                                OR (DATEPART(mi, @dateFrom) = DATEPART(mi, @dateTo) AND DATEPART(ss, @dateFrom) > DATEPART(ss, @dateTo))
                                OR (DATEPART(ss, @dateFrom) = DATEPART(ss, @dateTo) AND DATEPART(ms, @dateFrom) > DATEPART(ms, @dateTo))
                                THEN 1
                                ELSE 0
                            END
SELECT @tmpdate         = DATEADD(yy, @years, @tmpdate)
SELECT @months          = DATEDIFF(mm, @tmpdate, @dateTo)
                            - CASE WHEN
                                   (DATEPART(dd, @dateFrom) > DATEPART(dd, @dateTo))
                                OR (DATEPART(dd, @dateFrom) = DATEPART(dd, @dateTo) AND DATEPART(hh, @dateFrom) > DATEPART(hh, @dateTo))
                                OR (DATEPART(hh, @dateFrom) = DATEPART(hh, @dateTo) AND DATEPART(mi, @dateFrom) > DATEPART(mi, @dateTo))
                                OR (DATEPART(mi, @dateFrom) = DATEPART(mi, @dateTo) AND DATEPART(ss, @dateFrom) > DATEPART(ss, @dateTo))
                                OR (DATEPART(ss, @dateFrom) = DATEPART(ss, @dateTo) AND DATEPART(ms, @dateFrom) > DATEPART(ms, @dateTo))
                                THEN 1
                                ELSE 0
                            END
SELECT @tmpdate         = DATEADD(mm, @months, @tmpdate)
SELECT @days            = DATEDIFF(dd, @tmpdate, @dateTo)
                            - CASE WHEN
                                   (DATEPART(hh, @dateFrom) > DATEPART(hh, @dateTo))
                                OR (DATEPART(hh, @dateFrom) = DATEPART(hh, @dateTo) AND DATEPART(mi, @dateFrom) > DATEPART(mi, @dateTo))
                                OR (DATEPART(mi, @dateFrom) = DATEPART(mi, @dateTo) AND DATEPART(ss, @dateFrom) > DATEPART(ss, @dateTo))
                                OR (DATEPART(ss, @dateFrom) = DATEPART(ss, @dateTo) AND DATEPART(ms, @dateFrom) > DATEPART(ms, @dateTo))
                                THEN 1
                                ELSE 0
                            END
SELECT @tmpdate         = DATEADD(dd, @days, @tmpdate)
SELECT @hours           = DATEDIFF(hh, @tmpdate, @dateTo)
                            - CASE WHEN
                                   (DATEPART(mi, @dateFrom) > DATEPART(mi, @dateTo))
                                OR (DATEPART(mi, @dateFrom) = DATEPART(mi, @dateTo) AND DATEPART(ss, @dateFrom) > DATEPART(ss, @dateTo))
                                OR (DATEPART(ss, @dateFrom) = DATEPART(ss, @dateTo) AND DATEPART(ms, @dateFrom) > DATEPART(ms, @dateTo))
                                THEN 1
                                ELSE 0
                            END
SELECT @tmpdate         = DATEADD(hh, @hours, @tmpdate)
SELECT @minutes         = DATEDIFF(mi, @tmpdate, @dateTo)
                            - CASE WHEN
                                   (DATEPART(ss, @dateFrom) > DATEPART(ss, @dateTo))
                                OR (DATEPART(ss, @dateFrom) = DATEPART(ss, @dateTo) AND DATEPART(ms, @dateFrom) > DATEPART(ms, @dateTo))
                                THEN 1
                                ELSE 0
                            END
SELECT @tmpdate         = DATEADD(mi, @minutes, @tmpdate)
SELECT @seconds         = DATEDIFF(ss, @tmpdate, @dateTo)
                            - CASE WHEN
                                   (DATEPART(ms, @dateFrom) > DATEPART(ms, @dateTo))
                                THEN 1
                                ELSE 0
                            END
SELECT @tmpdate         = DATEADD(ss, @seconds, @tmpdate)
SELECT @milliseconds    = DATEDIFF(ms, @tmpdate, @dateTo)

SELECT
    @sign AS [sign]
    , @years AS [years]
    , @months AS [months]
    , @days AS [days]
    , @hours AS [hours]
    , @minutes AS [minutes]
    , @seconds AS [seconds]
    , @milliseconds AS [milliseconds]
于 2012-06-25T10:03:42.610 に答える