【问题标题】:How to perform Case statement inside a select statement?如何在 select 语句中执行 Case 语句?
【发布时间】:2021-09-15 20:46:44
【问题描述】:

如果 datediff 函数返回空值,我想在列上放置“无记录”而不是 NULL

SELECT concat(e.firstname ,e.lastname) as Fullname,c.shiftcode as Shift, cast(c.datecheckinout as date) Date,datename(month, c.datecheckinout) as RecordMonth,c.timein , c.timeout,
CAST( 
    CASE
    WHEN (datediff(HOUR,c.timein,c.timeout)  IS NULL) 
    THEN 'No record'
    END 
    ), FROM tblCheckInOutDetail c  RIGHT JOIN tblEmployee e on e.IdEmployee = c.IdEmployee   WHERE e.IdEmployee = 55



到目前为止,此代码仅在“CAST”附近抛出不正确的语法,应为“AS”。但我不知道应该在 CAST 参数中输入什么数据类型,因为如果有记录,它将显示日期时间。

【问题讨论】:

  • 尝试删除演员表,但我得到了,但它抛出 将 varchar 值“无记录”转换为数据类型 int 时转换失败。 ` CASE WHEN (datediff(HOUR,c. timein,c.timeout) IS NULL) THEN 'No record' ELSE (datediff(HOUR,c.timein,c.timeout) ) END `
  • ISNULL(datediff(HOUR,c.timein,c.timeout),'n/No Record') as H 也不起作用
  • 鉴于您有 c.timein 和 c.timeout 列,我们可以假设 c.datecheckinout 是 DATE 吗?如果是这样,你为什么要投它?如果不是,为什么不使用该列的日期数据类型?您应该为用作列的表达式提供良好的别名。并且请在您的原始帖子中添加任何有用的信息,而不是作为列。
  • 嗨,@smor。是的 c.datecheckinout 是一个日期时间,我只想获取日期格式。是的,谢谢你的提醒。谢谢大佬。

标签: sql sql-server


【解决方案1】:

您需要将数字值转换为字符串。为此,您可以使用coalesce()

SELECT concat(e.firstname ,e.lastname) as Fullname,c.shiftcode as Shift, cast(c.datecheckinout as date) Date,datename(month, c.datecheckinout) as RecordMonth,c.timein , c.timeout,
       COALESCE(CAST(datediff(HOUR, c.timein, c.timeout) AS VARCHAR(255)), 'No record')
FROM tblEmployee e LEFT JOIN
     tblCheckInOutDetail c 
     ON e.IdEmployee = c.IdEmployee
WHERE e.IdEmployee = 55;

注意:我将RIGHT JOIN 切换为LEFT JOIN。它们在逻辑上是等价的。但是大多数人发现遵循LEFT JOIN 的逻辑要容易得多,因为定义行的表是FROM 子句中读取的第一个表。

【讨论】:

  • 谢谢,这也是另一个可行的选择。
【解决方案2】:

严格回答问题(虽然我不明白为什么你需要CASE expression,如果你有查询的工​​作版本),你可以轻松地将其转换为CASE 表达式:

ISNULL(CAST(datediff(HOUR,c.timein,c.timeout) as varchar),'No Record')

ISNULL 真的很好,CASE WHEN a IS NOT NULL THEN a ELSE b END 的方便简写,所以:

CASE WHEN DATEDIFF(HOUR, c.timein, c.timeout) IS NOT NULL
  THEN CAST(datediff(HOUR,c.timein,c.timeout) as varchar(11))
  ELSE 'No Record' END

如您所见,一个缺点是,如果您真的很想要 CASE 表达式,您必须至少重复 DATEDIFF 以涵盖外行不存在的情况和情况其中外行存在,但其中一个值为NULL

另请注意,您应该always specify a length for variable types like varchar,即使您认为使用默认设置是安全的。

【讨论】:

    【解决方案3】:

    我不知道这是否是正确的选项或用法。

    但这对我有用:

    ISNULL(CAST(datediff(HOUR,c.timein,c.timeout) as varchar),'No Record')
    

    但是你们能告诉我如何使用 case 表达式来做到这一点吗?

    【讨论】:

    • don't cast as varchar without specifying the length,即使你知道你不需要它。另外,CASE is an expression,不是声明,这里的语义可能非常重要。最后,如果您有多个版本的查询都在工作,为什么您需要一个带有CASE 表达式的如此糟糕的版本?
    • 感谢您的洞察力。我正在考虑从 c.timein 显示当前时间计算,而 c.timeout 列没有记录。希望你能理解。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-04-04
    • 2023-04-07
    • 1970-01-01
    • 2014-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多