SQL中的多个CASE语句需要格式化

时间:2014-06-11 09:25:29

标签: sql sql-server tsql

我正在寻找一种更好的方式来编写这个案例陈述。场景就像这样

每周 - DateFrom是星期一,DateTo是星期日 每月 - 整月 每年 - 全年

但是,如果覆盖日期限制了每周,每月和每年的日期范围,则应考虑这些日期。以下作品但看起来很糟糕

 SELECT @dateMax =
       CASE @dateFrequency
            WHEN 'Daily' THEN @dateMax
            WHEN 'Weekly' THEN  
                CASE WHEN  @OverrideDateMax < DATEADD(WK, 1, (DateAdd(d, -(DatePart(dw,@dateMin) -1), @dateMin))) 
                    THEN DATEADD(DAY,1,@OverrideDateMax)
                ELSE 
                    DATEADD(WK, 1, (DateAdd(d, -(DatePart(dw,@dateMin) -1), @dateMin))) 
                END 
            WHEN 'Monthly' THEN 
                CASE WHEN @OverrideDateMax < DATEADD(MONTH,1,DATEADD(MONTH, DATEDIFF(MONTH, 0, @dateMax), 0))
                    THEN DATEADD(DAY,1, @OverrideDateMax)
                ELSE 
                    DATEADD(MONTH,1,DATEADD(MONTH, DATEDIFF(MONTH, 0, @dateMax), 0))
                END 
            WHEN 'Yearly' THEN 
                CASE WHEN  @OverrideDateMax < DATEADD(Year,1, DATEADD(YEAR, DATEDIFF(Year, 0, @dateMax),0))
                    THEN DATEADD(DAY,1, @OverrideDateMax)
                ELSE                        
                    DATEADD(Year,1, DATEADD(YEAR, DATEDIFF(Year, 0, @dateMax),0))
                END 
        END,
        @dateMin = 
        CASE @dateFrequency
            WHEN 'Daily' THEN @dateMin
            WHEN 'Weekly' THEN 
                CASE WHEN  @OverrideDateMin > DateAdd(d,  -(DatePart(dw,@dateMin) -1), @dateMin) 
                    THEN @OverrideDateMin 
                ELSE 
                    DateAdd(d,  -(DatePart(dw,@dateMin) -1), @dateMin)
                END 
            WHEN 'Monthly' THEN 
                CASE WHEN  @OverrideDateMin > @dateMin  THEN 
                    @OverrideDateMin
                ELSE 
                    DATEADD(MONTH, DATEDIFF(MONTH, 0, @dateMin), 0)
                END
            WHEN 'Yearly' THEN 
                CASE WHEN  @OverrideDateMin > @dateMin  THEN 
                    @OverrideDateMin
                ELSE    
                    DATEADD(Year, DATEDIFF(YEAR, 0, @dateMin), 0)
                END
        END

2 个答案:

答案 0 :(得分:0)

如果您的逻辑是合理的并且您对此感到满意,那么我倾向于整理格式并添加一些解释性评论。

 SELECT @dateMax =
       CASE @dateFrequency
            WHEN 'Daily' 
            -- When Daily, always take the date max   
            THEN @dateMax
            WHEN 'Weekly'
            -- When Weekly Special logic applies   
            THEN    CASE
                        -- if an override date is specified which is less than (describe function)    
                        WHEN @OverrideDateMax < DATEADD(WK, 1, (DateAdd(d, -(DatePart(dw,@dateMin) -1), @dateMin))) 
                        -- the use one day beyond the override
                        THEN DATEADD(DAY,1,@OverrideDateMax)
                        -- otherwise use (describe function)
                        ELSE DATEADD(WK, 1, (DateAdd(d, -(DatePart(dw,@dateMin) -1), @dateMin))) 
                    END 
            WHEN 'Monthly' 
            THEN    CASE 
                        WHEN @OverrideDateMax < DATEADD(MONTH,1,DATEADD(MONTH, DATEDIFF(MONTH, 0, @dateMax), 0))
                        THEN DATEADD(DAY,1, @OverrideDateMax)
                        ELSE DATEADD(MONTH,1,DATEADD(MONTH, DATEDIFF(MONTH, 0, @dateMax), 0))
                    END 
            WHEN 'Yearly' 
            THEN    CASE 
                        WHEN  @OverrideDateMax < DATEADD(Year,1, DATEADD(YEAR, DATEDIFF(Year, 0, @dateMax),0))
                        THEN DATEADD(DAY,1, @OverrideDateMax)
                        ELSE DATEADD(Year,1, DATEADD(YEAR, DATEDIFF(Year, 0, @dateMax),0))
                    END 
        END

有一些常见的函数可以被提取并放入标量值函数中,这可能会提高可读性。例如

这出现两次

DATEADD(WK, 1, (DateAdd(d, -(DatePart(dw,@dateMin) -1), @dateMin))) 

你可以放入

CREATE FUNCTION [dbo].[WeekDateMax]
(
    @dateMin DateTime
)
RETURNS DateTime
AS
BEGIN

    RETURN DATEADD(WK, 1, (DateAdd(d, -(DatePart(dw,@dateMin) -1), @dateMin)))
END
GO

然后简化你的最新每周块日期

THEN    CASE
        -- if an override date is specified which is less than (describe function)    
        WHEN @OverrideDateMax < [dbo].[WeekDateMax](@dateMin)
        -- the use one day beyond the override
        THEN DATEADD(DAY,1,@OverrideDateMax)
        -- otherwise use (describe function)
        ELSE [dbo].[WeekDateMax](@dateMin)

答案 1 :(得分:0)

我会这样打破它。

DECLARE @WeekMin AS datetime = DateAdd(d,  -(DatePart(dw,@dateMin) -1), @dateMin);
DECLARE @WeekMax AS datetime = DATEADD(WK, 1, (DateAdd(d, -(DatePart(dw, @dateMin) -1), @dateMin)));
DECLARE @MonthMin AS datetime = DATEADD(MONTH, DATEDIFF(MONTH, 0, @dateMin), 0);
DECLARE @MonthMax AS datetime = DATEADD(MONTH,1,DATEADD(MONTH, DATEDIFF(MONTH, 0, @dateMax), 0));
DECLARE @YearMin AS datetime = DATEADD(Year, DATEDIFF(YEAR, 0, @dateMin), 0);
DECLARE @YearMax AS datetime = DATEADD(Year,1, DATEADD(YEAR, DATEDIFF(Year, 0, @dateMax),0));

SET @dateMin = CASE @dateFrequency
                    WHEN 'Daily' THEN @dateMin
                    WHEN 'Weekly' THEN @WeekMin
                    WHEN 'Monthly' THEN @MonthMin
                    WHEN 'Yearly' THEN @YearMin
               END;
SET @dateMin = CASE WHEN @OverrideDateMin > @dateMin 
                    THEN @OverrideDateMin
                    ELSE @dateMin
               END;

SET @dateMax = CASE @dateFrequency
                    WHEN 'Daily' THEN @dateMax
                    WHEN 'Weekly' THEN @WeekMax
                    WHEN 'Monthly' THEN @MonthMax
                    WHEN 'Yearly' THEN @YearMax
               END;
SET @dateMax = CASE WHEN @OverrideDateMax < @dateMax 
                    THEN @OverrideDateMax
                    ELSE @dateMax
               END;