Tsql SQL根据3个日期范围返回一个值
我有问题排序在3个不同的日期范围内的一些日期,并返回一个值根据正确的范围。我希望你能给我一个高效干净的方法 我从SQL表中得到了6个不同的日期。这些日期随后存储在变量中。所有日期也可以是空值。我的日期分为3个日期范围。我想通过使用我所有范围中最早的开始日期来返回我所处范围的指示。正确范围的日期也必须小于当前日期。日期范围也只能由结束日期组成。在这种情况下,我们认为范围在结束日期结束,并且在此之前处于活动状态。在这种情况下,我们选择接近当前日期的最早结束日期 如果所有日期都为空,则返回0 范围#1(类别#1)X开始日期和X结束日期返回1 范围2(类别2)Y开始日期和Y结束日期返回2 范围#3(类别#3)Z开始日期和Z结束日期返回3 编辑 有没有比做很多IF语句更有效的方法?我很难处理所有这些条件和检查。这里是我到目前为止的一个片段Tsql SQL根据3个日期范围返回一个值,tsql,sorting,date,validation,datetime,Tsql,Sorting,Date,Validation,Datetime,我有问题排序在3个不同的日期范围内的一些日期,并返回一个值根据正确的范围。我希望你能给我一个高效干净的方法 我从SQL表中得到了6个不同的日期。这些日期随后存储在变量中。所有日期也可以是空值。我的日期分为3个日期范围。我想通过使用我所有范围中最早的开始日期来返回我所处范围的指示。正确范围的日期也必须小于当前日期。日期范围也只能由结束日期组成。在这种情况下,我们认为范围在结束日期结束,并且在此之前处于活动状态。在这种情况下,我们选择接近当前日期的最早结束日期 如果所有日期都为空,则返回0 范围#1
--Return 0 is not Condition is Applicable
ALTER PROCEDURE [dbo].[HO_GetReason]
@HOID INT
AS
BEGIN
Declare @IsHOIDReal INT = (SELECT ID from T_HO where id = @HOID)
Declare @XStartDate Datetime
Declare @XEndDate Datetime
Declare @YStartDate Datetime
Declare @YEndDate Datetime
Declare @ZStartDate Datetime
Declare @ZEndDate Datetime
CREATE TABLE #tmpT_HO_Withhold (
ID INT NOT NULL,
XStartDate Datetime null,
XEndDate Datetime null,
YStartDate Datetime null,
YEndDate Datetime null,
ZStartDate Datetime null,
ZEndDate Datetime null,
PRIMARY KEY CLUSTERED (ID)
)
IF (@IsHOIDReal IS NOT NULL)
BEGIN
INSERT INTO #tmpT_HO_Withhold
SELECT T_HO.ID,
XStartDate ,
XEndDate ,
YStartDate ,
YEndDate ,
ZStartDate ,
ZEndDate
FROM dbo.T_HO
WHERE ID = @HOID
SET @XStartDate = (Select TOP 1 XStartDate from #tmpT_HO_Withhold)
SET @XEndDate = (Select TOP 1 XEndDate from #tmpT_HO_Withhold)
SET @YStartDate = (Select TOP 1 YStartDate from #tmpT_HO_Withhold)
SET @YEndDate = (Select TOP 1 YEndDate from #tmpT_HO_Withhold)
SET @ZStartDate = (Select TOP 1 ZStartDate from #tmpT_HO_Withhold)
SET @ZEndDate = (Select TOP 1 ZEndDate from #tmpT_HO_Withhold)
IF(@XStartDate IS NULL AND @YStartDate IS NULL AND @ZStartDate IS NULL)
BEGIN print 'NO CONDITION' Select 0 as 'HO_GetReason' END
ELSE IF (@XStartDate IS NOT NULL AND @YStartDate IS NULL AND @ZStartDate IS NULL) BEGIN print '1' Select 1 as 'HO_GetReason'END
ELSE IF (@XStartDate IS NOT NULL AND @YStartDate IS NULL AND @ZStartDate IS NULL) BEGIN print '2' Select 2 as 'HO_GetReason'END
ELSE IF (@XStartDate IS NULL AND @YStartDate IS NULL AND @ZStartDate IS NOT NULL) BEGIN print '3' Select 3 as 'HO_GetReason'END
END
DROP TABLE #tmpT_HO_Withhold END
关于高效和清洁的说明: 复杂条件不属于低效类别。它可以归入难以阅读的类别并进行维护,但它们是一个非常快速的操作
- 示例:第二个“else-if”与第一个“else-if”看起来很奇怪。无法访问代码
- 使用#tablename的临时表在存储过程中不是并发安全的,在某些情况下可能会出现奇数的模式更改错误
SELECT
@XStartDate = XStartDate ,
@XEndDate = XEndDate ,
@YStartDate = YStartDate ,
@YEndDate = YEndDate ,
@ZStartDate = ZStartDate ,
@ZEndDate = ZEndDate
FROM dbo.T_HO
WHERE ID = @HOID
根据create表中的主键,Id是唯一的,因此在这种格式中不需要TOP,任何行都不会将值保留为null
就我个人而言,一旦我得到了条件工作(绝对最终形式),我就会直接将其调整为CASE语句,并将其设置为基表中的持久计算列
ALTER TABLE dbo.T_HO ADD Reason AS (CASE WHEN XStartDate IS NOT NULL AND ... THEN ... WHEN ... THEN ... ELSE 0 END) PERSISTED
样本数据和预期结果将有所帮助。他们应该澄清“在我的所有范围内使用最早的开始日期”和按顺序检查X、Y、Z日期以及使用第一个匹配作为结果而不比较开始日期之间的混淆。“也必须小于当前日期”,而不与当前日期进行任何比较?如果多个开始日期为空(或在将来),那么如何选择结果,例如最早的结束日期>=今天?我用一些我正在尝试做的示例来回答我的问题。请看一看。
ALTER TABLE dbo.T_HO ADD Reason AS (CASE WHEN XStartDate IS NOT NULL AND ... THEN ... WHEN ... THEN ... ELSE 0 END) PERSISTED