Tsql SQL根据3个日期范围返回一个值

Tsql SQL根据3个日期范围返回一个值,tsql,sorting,date,validation,datetime,Tsql,Sorting,Date,Validation,Datetime,我有问题排序在3个不同的日期范围内的一些日期,并返回一个值根据正确的范围。我希望你能给我一个高效干净的方法 我从SQL表中得到了6个不同的日期。这些日期随后存储在变量中。所有日期也可以是空值。我的日期分为3个日期范围。我想通过使用我所有范围中最早的开始日期来返回我所处范围的指示。正确范围的日期也必须小于当前日期。日期范围也只能由结束日期组成。在这种情况下,我们认为范围在结束日期结束,并且在此之前处于活动状态。在这种情况下,我们选择接近当前日期的最早结束日期 如果所有日期都为空,则返回0 范围#1

我有问题排序在3个不同的日期范围内的一些日期,并返回一个值根据正确的范围。我希望你能给我一个高效干净的方法

我从SQL表中得到了6个不同的日期。这些日期随后存储在变量中。所有日期也可以是空值。我的日期分为3个日期范围。我想通过使用我所有范围中最早的开始日期来返回我所处范围的指示。正确范围的日期也必须小于当前日期。日期范围也只能由结束日期组成。在这种情况下,我们认为范围在结束日期结束,并且在此之前处于活动状态。在这种情况下,我们选择接近当前日期的最早结束日期

如果所有日期都为空,则返回0

范围#1(类别#1)X开始日期和X结束日期返回1

范围2(类别2)Y开始日期和Y结束日期返回2

范围#3(类别#3)Z开始日期和Z结束日期返回3

编辑

有没有比做很多IF语句更有效的方法?我很难处理所有这些条件和检查。这里是我到目前为止的一个片段

    --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