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:
这样case语句就不需要区分它们了。
我正在为这个函数获取正确的输出。 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:
这样case语句就不需要区分它们了。