SQL 计算有问题 - datediff 给我带来麻烦

Trouble with TSQL calculation - date diff giving me troubles

我正在为这个函数获取正确的输出。 datediff 是否只计算同月天数的天数差异? 当我以“2015 年 1 月 1 日”的形式传递日期时,它总是发回 0 =/ 我是否遗漏了我的逻辑或语法中的某些内容?

CREATE FUNCTION dbo.CanPolicy
(
    @ReservationID int,
    @CancellationDate date
)
RETURNS smallmoney
AS
    BEGIN
        DECLARE @DepositPaid smallmoney
        SET @DepositPaid = (SELECT ResDepositPaid
                            FROM Reservation
                            WHERE ReservationID = @ReservationID)
        DECLARE @ResDate date
        SET @ResDate = (SELECT ResDate
                        FROM Reservation
                        WHERE ReservationID = @ReservationID)
        DECLARE @CanceledDaysAhead int
        SET @CanceledDaysAhead = DATEDIFF(day, @ResDate, @CancellationDate)
        DECLARE @result smallmoney
        SET @result = 0
        SET @result = CASE WHEN @CanceledDaysAhead > 30 THEN 0
                        WHEN @CanceledDaysAhead BETWEEN 14 AND 30 THEN @DepositPaid * 0.25 + 25
                        WHEN @CanceledDaysAhead BETWEEN 8 AND 13 THEN @DepositPaid * 0.50 + 25
                        ELSE @DepositPaid
                    END
        RETURN @result
    END

GO

不,DATEDIFF 计算两者之间的日期。尝试:

SELECT DATEDIFF(day,{ts'2105-01-01 00:00:00'},{ts'2105-04-01 00:00:00'})

可能是日期格式问题...

您确定@ResDate 设置正确吗?

编辑:CTE 的新方法

DECLARE @ReservationID INT=123;
DECLARE @CancelationDate DATE=GETDATE();

WITH ReservationCTE AS
(
    SELECT ResDepositPaid 
          ,ResDate
    FROM Reservation
    WHERE ReservationID=@ReservationID --assuming that ReservationID is a unique key!
)
,ReservationCTEWithDateDiff AS
(
    SELECT ReservationCTE.*
          --EDIT: switched dates due to a comment by Me.Name
          ,DATEDIFF(DAY,@CancelationDate,ResDate) AS CanceledDaysAhead
    FROM ReservationCTE
)
SELECT CASE WHEN CanceledDaysAhead>30 THEN 0
            WHEN CanceledDaysAhead BETWEEN 14 AND 30 THEN ResDepositPaid * 0.25 + 25
            WHEN CanceledDaysAhead BETWEEN 8 AND 13 THEN ResDepositPaid * 0.50 + 25
            ELSE ResDepositPaid END AS MyReturnValue
FROM ReservationCTEWithDateDiff

我认为你的函数的正确和简短版本是这个 - 请试一试:

CREATE FUNCTION dbo.CanPolicy
(
    @ReservationID int,
    @CancellationDate date
)
RETURNS smallmoney
AS
    BEGIN
        DECLARE @DepositPaid smallmoney,
                @CanceledDaysAhead int

        SELECT  @DepositPaid = ResDepositPaid,
                @CanceledDaysAhead = DATEDIFF(DAY,ResDate,@CancellationDate)
        FROM    Reservation
        WHERE   ReservationID = @ReservationID


        RETURN CAST(CASE WHEN @CanceledDaysAhead > 30 THEN 0 ELSE
               CASE WHEN @CanceledDaysAhead BETWEEN 14 AND 30 THEN @DepositPaid * 0.25 + 25 ELSE
               CASE WHEN @CanceledDaysAhead BETWEEN 8 AND 13 THEN @DepositPaid * 0.50 + 25 ELSE
               @DepositPaid END END END AS smallmoney)

    END
GO

主要问题是你的情况——我认为什么时候阻塞...

你现在可能已经解决了这个问题,但是我处理日期差异的一种方法是使用 ABS:

ABS on MSDN

这样case语句就不需要区分它们了。