【问题标题】:Convert IF THEN ELSE from Excel to SQL将 IF THEN ELSE 从 Excel 转换为 SQL
【发布时间】:2018-01-24 18:19:15
【问题描述】:

我正在尝试将此 excel 公式转换为 SQL,但我真的不知道该怎么做。

=IF(WEEKDAY(INT(DateDB))=2;INT([DateR])=INT([DateDB]])-3;INT([DateR])=INT([DataDB])-1)

我从 CASE 开始,但我没有得到任何结果

CASE WHEN DATEPART(dw, CONVERT(DATE, [DataDB], 105)) = 2  THEN

【问题讨论】:

  • 您使用的是哪个DBMS 产品? “SQL”只是一种查询语言,不是特定数据库产品的名称。
  • 此外,显示 DateRDateDB 的现有值,以及这些日期的 Excel 公式的结果,可能有助于我们准确了解您现在得到什么以及您期望得到什么从您正在使用的 DBMS 获取。
  • 我使用的是 SQL Server 2012。日期格式为 yyyy-mm-dd hh:mm:ss。我使用 CONVERT 命令只是为了比较日期(yyyy-mm-dd),而忽略了时间值。我需要得到一个 TRUE 或 FALSE,这取决于工作日是否等于 2。
  • 如果DateDBdatedatetime 类型,则不需要convert

标签: sql-server sql-server-2012 excel case


【解决方案1】:

我刚刚找到了答案。也许有一个简单的方法。

CASE WHEN DATEPART(dw, CONVERT(DATE, [DateBD], 105)) = 2  AND 
    CONVERT(DATE, [DateR], 105) = DATEADD(DAY, -3, CONVERT(DATE, [DateBD], 105)) THEN 'TRUE'
     WHEN DATEPART(dw, CONVERT(DATE, [DateBD], 105)) = 2  AND 
    CONVERT(DATE, [DateR], 105) <> DATEADD(DAY, -3, CONVERT(DATE, [DateBD], 105)) THEN 'FALSE'
     WHEN DATEPART(dw, CONVERT(DATE, [DateBD], 105)) <> 2 AND 
    CONVERT(DATE, [DateR], 105) = DATEADD(DAY, -1, CONVERT(DATE, [DateBD], 105)) THEN 'TRUE' ELSE 'FALSE'
END as [myValue]

【讨论】:

    【解决方案2】:

    根据您的 Excel 公式,您似乎正在尝试执行类似...

    If "Day 1" is Tuesday 
        Check That "Day 2" is 3 days prior
    Otherwise
        Check That "Day 2" is 1 day prior
    

    如果是这种情况,上述案例陈述的稍微清晰的版本可能看起来像...

    declare 
        @dt1 date = '2018-01-25',
        @dt2 date = '2018-01-22';
    
    with cte as (
        select 
            diff = datediff(day,@dt1,@dt2),
            dow1 = datepart(weekday,@dt1)
    ) 
    select 
        case dow1
            when 2 then 
                (case when diff = -3 then 'yes' else 'no' end)
            else 
                (case when diff = -1 then 'yes' else 'no' end)
    from cte
    

    我鼓励您查看 the datefirst page 以了解您的实例的星期几设置。

    【讨论】:

      【解决方案3】:

      您实际上希望在以下复杂条件下返回 True:

      • DateDB 的工作日是 2

        DateR 和 DateDB 相差 3 天

      • DateDB 的工作日是不是 2

        DateR 和 DateDB 之间的差异是 1 天。

      否则你想返回 False。

      您可以将上述实现为对单个复杂条件的检查,从而最终得到一个只有两个分支的条件,一个 THEN 和一个 ELSE

      CASE
        WHEN (DATEPART(WEEKDAY, DateDB) =  2 AND DATEDIFF(DAY, DateR, DateDB) = 3)
          OR (DATEPART(WEEKDAY, DateDB) <> 2 AND DATEDIFF(DAY, DateR, DateDB) = 1)
        THEN 'TRUE'
        ELSE 'FALSE'
      END
      

      请注意,您不必将日期时间值转换为日期类型来确定其工作日。避免转换会使您的 DATEPART 表达式更加紧凑。

      而不是将日期与另一个日期减去一定天数进行比较,您只需计算两个日期之间的天数差并将其与所需值进行比较即可。再次将其翻转的好处是,您无需将两个日期时间值转换为日期,从而得到更紧凑(因此可能更清晰)的比较表达式。

      现在上面的解决方案肯定比你想出的更简洁,但是如果你把逻辑放在上面,有一种方法可以让它更简洁。像这样:

      • 如果 DateR 和 DateDB 之间的差异是 3(如果 DateDB 的工作日是 2)或 1(否则),
        那么是的,
        否则为假。

      虽然更晦涩难懂,但上述逻辑可以以一种避免重复相同表达式的方式呈现,使结果更紧凑,尽管有条件嵌套。你自己看看它是否足够清晰:

      CASE DATEDIFF(DAY, DateR, DateDB)
        WHEN (CASE DATEPART(WEEKDAY, DateDB) WHEN 2 THEN 3 ELSE 1 END)
        THEN 'TRUE'
        ELSE 'FALSE'
      END
      

      顺便说一句,SQL Server 支持一个名为IIF() 的函数,它与 Excel 的IF() 函数基本相同,只是不能在 Then 或 Else 部分使用布尔表达式,这排除了直接将 IF 转换为 Transact-SQL IIF。但是,您可以使用 IIF 在此答案中重写这两种解决方案:

      1. IIF(
          (DATEPART(WEEKDAY, DateDB) =  2 AND DATEDIFF(DAY, DateR, DateDB) = 3)
          OR (DATEPART(WEEKDAY, DateDB) <> 2 AND DATEDIFF(DAY, DateR, DateDB) = 1),
          'TRUE',
          'FALSE'
        )
        
      2. IIF(DATEDIFF(DAY, DateR, DateDB) = IIF(DATEPART(WEEKDAY, DateDB) = 2, 3, 1), 'TRUE', 'FALSE')
        

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-03-08
        • 2021-08-30
        • 2019-04-09
        • 1970-01-01
        • 2014-04-13
        相关资源
        最近更新 更多