sql中的嵌套case语句为date

时间:2015-08-24 01:50:15

标签: sql sql-server

我想知道我做错了什么。我想要做的是获得每个月的一半,让我们说如果我输入2015年8月1日它应该返回2015年7月16日如果我使用2015年8月31日它应该返回8/15/2015 。我创建了一个没有运行的Sql脚本,这里是代码。

SELECT case when @rank = 'R' 
then month(DATEADD(day, -15, @date_from)+'/'+ 
case when day(DATEADD(day, -15, @date_from)) between 1 and 15 then 1 else 16 end
+'/'+year(DATEADD(day, -15, @date_from) 
DATEADD(month, -1, @date_from)
end

但我收到错误,有没有办法让我更有效地做到这一点?我的错误解决方案是什么?

5 个答案:

答案 0 :(得分:0)

我正在创建一个子查询先生,完整的代码看起来像这样

set @refdatefrom = 
(
SELECT case when @rank = 'R' 
then month(DATEADD(day, -15, @date_from)+'/'+ 
case when day(DATEADD(day, -15, @date_from)) between 1 and 15 then 1 else 16 end
+'/'+year(DATEADD(day, -15, @date_from) 
DATEADD(month, -1, @date_from)
end
)

然后我将添加的每个值将插入表中。我得到的错误是

Server: Msg 156, Level 15, State 1, Procedure finalize, Line 65
Incorrect syntax near the keyword 'end'.
Server: Msg 156, Level 15, State 1, Procedure finalize, Line 107
Incorrect syntax near the keyword 'end'.

答案 1 :(得分:0)

DECLARE @date DATE = '8/15/2015'

SELECT  CASE 
             WHEN DAY(@date) <= 15 AND @rank = 'R'  
            THEN  DATEADD(MONTH, DATEDIFF(MONTH, 0, @date) -1, 0) + 14 
             WHEN DAY(@date) > 15 AND @rank = 'R' 
            THEN DATEADD(MONTH, DATEDIFF(MONTH, 0, @date), 0) + 14
        END

您可以为您的变量分配值...

SELECT @refdatefrom =  CASE 
                             WHEN DAY(@date) <= 15 AND @rank = 'R'  
                            THEN  DATEADD(MONTH, DATEDIFF(MONTH, 0, @date) -1, 0) + 14 
                             WHEN DAY(@date) > 15 AND @rank = 'R' 
                            THEN DATEADD(MONTH, DATEDIFF(MONTH, 0, @date), 0) + 14
                        END

答案 2 :(得分:0)

您的代码中有不匹配的括号。试试这个来清理它:

SELECT 
    case
        when @rank = 'R' 
            then month(DATEADD(day, -15, @date_from)) + '/' + 
                case 
                    when day(DATEADD(day, -15, @date_from)) between 1 and 15 then 1 
                    else 16 
                end
            + '/' + year(DATEADD(day, -15, @date_from))
        else DATEADD(month, -1, @date_from)
    end

然而,这仍然会产生错误说:

  

操作数类型碰撞:int与日期不兼容

要解决上述错误,您需要将ints转换为varchar并将else部分转换为varchar

SELECT 
    CASE
        WHEN @rank = 'R' 
            THEN CONVERT(VARCHAR(2), MONTH(DATEADD(DAY, -15, @date_from))) + '/' + 
                CASE 
                    WHEN DAY(DATEADD(DAY, -15, @date_from)) BETWEEN 1 AND 15 THEN '1'
                    ELSE '16'
                END
            + '/' + CONVERT(VARCHAR(4), YEAR(DATEADD(DAY, -15, @date_from)))
        ELSE CONVERT(VARCHAR(10), DATEADD(MONTH, -1, @date_from), 101)
    END

不使用sting连接的替代解决方案是:

SELECT
    CASE
        WHEN DAY(@date_from) < 15 THEN
            DATEADD(D, 15, DATEADD(MM, DATEDIFF(MM, 0, @date_from) - 1, 0))
        ELSE
            DATEADD(D, 15, DATEADD(MM, DATEDIFF(MM, 0, @date_from), 0))
    END

答案 3 :(得分:0)

我相信以下是您想要的:

  • 从该日期减去15天。你想要的是这个月的第15个月。
  • 因此,从该日期减去该月的日期。这是上个月的最后一天。
  • 添加(1 + 15天)以获得第15名。

这变成了一个没有case且没有字符串的SQL语句:

select datediff(day,
                16 - day(datediff(day, -15, @date_from)),
                datediff(day, -15, @date_from)
               )

答案 4 :(得分:0)

这是一个无效的陈述,因为它缺少一些括号,并且它可能在第一种情况下缺少else语句。我不确定这是否是你想要实现的目标。

DECLARE @rank AS VARCHAR(50) = 'R';
DECLARE @date_from AS DATETIME = '1/1/2015';

SELECT  CASE WHEN @rank = 'R'
        THEN
            CAST(
            -- get month
            Cast(Month(Dateadd( day, -15, @date_from )) AS VARCHAR(2)) + '/' + 
            -- get day
            CASE WHEN Day(Dateadd( day, -15, @date_from )) BETWEEN 1 AND 15 THEN '1' ELSE '16' END + '/' + 
            -- get year
            Cast(Year(Dateadd( day, -15, @date_from )) AS VARCHAR(5)) AS DATETIME)
        ELSE
            DATEADD(month, -1, @date_from)
        END