【问题标题】:SQL Server: How use 'case when' in query?SQL Server:如何在查询中使用“case when”?
【发布时间】:2012-11-27 08:04:33
【问题描述】:

我尝试将case whennullnot null 设置为值ErrorCode 字段。

例如

EmpNo|ChkDate                |ChkIn                  |ChkOut                 |ErrorCode
00001|2012-10-01 00:00:00.000|2012-10-01 07:21:00.000|2012-10-01 17:05:00.000|0
00002|2012-10-01 00:00:00.000|2012-10-01 22:17:00.000|2012-10-01 00:00:00.000|6
00003|2012-10-01 00:00:00.000|2012-10-01 00:00:00.000|2012-10-01 19:30:00.000|6
00004|2012-10-01 00:00:00.000|NULL                   |NULL                   |7
00005|2012-10-01 00:00:00.000|2012-10-01 07:10:00.000|2012-10-01 12:00:00.000|0
00006|2012-10-01 00:00:00.000|2012-10-01 13:50:00.000|2012-10-01 19:20:00.000|0

但我需要输出(错误代码)

EmpNo|ChkDate                |ChkIn                  |ChkOut                 |ErrorCode
00001|2012-10-01 00:00:00.000|2012-10-01 07:21:00.000|2012-10-01 17:05:00.000|0
00002|2012-10-01 00:00:00.000|2012-10-01 22:17:00.000|2012-10-01 00:00:00.000|6
00003|2012-10-01 00:00:00.000|2012-10-01 00:00:00.000|2012-10-01 19:30:00.000|6
00004|2012-10-01 00:00:00.000|NULL                   |NULL                   |7
00005|2012-10-01 00:00:00.000|2012-10-01 07:10:00.000|2012-10-01 12:00:00.000|8
00006|2012-10-01 00:00:00.000|2012-10-01 13:50:00.000|2012-10-01 19:20:00.000|8

在 ChkIn 和 ChkOut 中的值是半天。我需要设置值 = 8。但我尝试 = 0。

此代码:

SELECT
   tf.EmpNo, tf.ChkDate, tf.ChkIn, tf.ChkOut,
   CASE
      WHEN ChkIn is not null and Convert(nvarchar(10), ChkOut,108) != '00:00:00'
         THEN 0
      WHEN ChkIn is not null and Convert(nvarchar(10) ,ChkOut,108) = '00:00:00'
         THEN 6
      WHEN Convert(nvarchar(10),ChkIn,108) = '00:00:00' and ChkOut is not null
         THEN 6
      WHEN Convert(nvarchar(10),ChkOut,108) <= '12:00:00'
         OR Convert(nvarchar(10),ChkOut,108) >= '12:00:01' Then 8
      WHEN ChkIn is null and ChkOut is null THEN 7 
   END as 'ErrorCode'
FROM filesTA tf
WHERE tf.ChkDate = '2012-10-01'

【问题讨论】:

  • 为什么 EmpNo 1 得到代码 0,而 EmpNo 5 和 6 得到 8?你如何定义全天和半天?如果没有某种经过时间计算,您将无法区分那些,而且我无法从您现有的查询中判断逻辑应该是什么。请更清楚地解释何时应将值 0、6、7 和 8 应用于一行。

标签: sql-server database sql-server-2008-r2 case-when


【解决方案1】:

问题似乎是您的条件“重叠”。我的意思是早期条件适用(在您的情况下:第一个条件),后面的条件也适用,但 case 语句在第一次匹配时结束。

您需要做的是重新表述您的条件,以便它们唯一地识别每个案例。

您的第一个条件是 ChkIn 不应为 null 并且 ChkOut 不应等于 00:00:00。虽然对于您期望结果为8 的行,此条件也成立,但case 语句应用了第一个“匹配”。

编辑
但是,我不太了解您对何时预期输出为0 以及何时预期为8 的要求。也许您可以进一步解释应该返回哪个值的确切条件。我无法理解 在 ChkIn 中的值,而 ChkOut 是半天。我需要设置值 = 8。

【讨论】:

    【解决方案2】:

    您必须在您的案例陈述中提供不会错误地返回 true 的条件。您可以尝试以下方法将计算提前 8:

    SELECT
       tf.EmpNo, tf.ChkDate, tf.ChkIn, tf.ChkOut,
       CASE
          WHEN Convert(nvarchar(10),ChkOut,108) <= '12:00:00'
             OR Convert(nvarchar(10),ChkOut,108) >= '12:00:01' Then 8
          WHEN ChkIn is not null and Convert(nvarchar(10), ChkOut,108) != '00:00:00'
             THEN 0
          WHEN ChkIn is not null and Convert(nvarchar(10) ,ChkOut,108) = '00:00:00'
             THEN 6
          WHEN Convert(nvarchar(10),ChkIn,108) = '00:00:00' and ChkOut is not null
             THEN 6
          WHEN ChkIn is null and ChkOut is null THEN 7 
       END as 'ErrorCode'
    FROM filesTA tf
    WHERE tf.ChkDate = '2012-10-01'
    

    但这只会让 0 永远不会出现。事实是你的愿望并不明确。为什么 EmpNo 1 得到代码 0,而 EmpNo 5 和 6 得到 8?你如何定义全天和半天?如果没有某种经过时间计算,您将无法区分那些,而且我无法从您现有的查询中判断逻辑应该是什么。请更清楚地解释何时应将值 0、6、7 和 8 应用于一行。

    【讨论】:

    • 知道。 知道。但他没有。这是他真正了解问题本质的一个例子。
    猜你喜欢
    • 1970-01-01
    • 2017-05-30
    • 2017-08-15
    • 1970-01-01
    • 1970-01-01
    • 2014-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多