【问题标题】:Substring in Where clauseWhere 子句中的子字符串
【发布时间】:2013-08-24 03:32:27
【问题描述】:

下面是我的查询,我正在寻找只有子字符串值(将是 YYYY)小于当前年份的记录 - 25 年......我应该提到这个字段是 varchar 并且可能需要被转换,我也未能成功。

SELECT 
            AccountNumber,
            LoanPrimeLongName,
            convert (varchar,LoanOpenDate,103)LoanOpenDate,
            LoanOriginalBalance,
            LoanBalance,
            LoanInterestRate,
            LoanRemainingTermMonths,
            LoanDelqDays,
            LoanDescription
FROM 
            ARCU.ARCULoanDetailed 
WHERE 
            (((LOANTYPE = '15'          OR
            LOANTYPE = '16'         OR
            LoanType = '17')            AND
            LoanStatus = 'Open')        AND
            ProcessDate = (CONVERT(VARCHAR, GETDATE(), 112)-1)) AND
            (SUBSTRING (loandescription,1,4) not like '%[^0-9]%')

ORDER BY AccountNumber

【问题讨论】:

  • 我是新手,不确定如何以更好的格式发布查询
  • 选择文本,然后按{}按钮,或按ctrl+k。

标签: sql substring varchar


【解决方案1】:

由于我们不知道您使用的是哪个 RDBMS,因此我将采用最简单的答案。这假设您使用的是 MSSQL。

使用ISNUMERIC() 函数来确定SUBSTRING(loandescription,1,4) 是否实际上是一个数字。如果是,那么您可以在此时转换/转换它并将其与您感兴趣的“年份”进行比较。IE:

        ...
        ProcessDate = (CONVERT(VARCHAR, GETDATE(), 112)-1)) AND
        (ISNUMERIC(SUBSTRING(loandescription,1,4)) = 1 AND 
        CAST(SUBSTRING(loandescription,1,4) AS INT) = (YEAR(GETDATE()) - 25))

由于布尔短路,如果前 4 个字符不是数字,那么它不会费心进行比较。相同的规则适用于其他 RDBMS 系统(例如 MySQL、PostgreSQL、SQLite 等),但方法可能有点不同。其实我觉得 MySQL 或者 PostgreSQL 连ISNUMERIC 函数都没有,这意味着你需要寻找其他方式(Regex)来测试。

【讨论】:

  • 由于 SQL Server 优化器的工作方式(大多数 SQL 优化器不使用短路,请参见此处:stackoverflow.com/a/1445911/109122),这不一定是安全的。您需要将测试(ISNUMERIC)放在CASE WHEN 条件表达式中,然后在其THEN 子句中隐藏用法(CAST)以确保安全。
【解决方案2】:

假设您的“YYYY”字段为(SUBSTRING (loandescription,1,4) not like '%[^0-9]%'):

AND CASE WHEN SUBSTRING (loandescription,1,4) not like '%[^0-9]%' 
            THEN CAST(SUBSTRING(loandescription,1,4)AS INT 
            ELSE YEAR(GETDATE()) 
     END < YEAR(DATEADD(year,-25,GETDATE()))

您需要CASE 语句,因为并不总是填充年份,并且文本值不会将CAST 设为INT。然后你使用 GETDATE() 函数和 DATEADD() 来添加你的 25 年标准。

【讨论】:

  • 我正在从描述示例“2005 Chevrolet Camaro”中提取一个子字符串,我正在尝试对年份进行子字符串化,然后仅提取 25 岁的值。我不断收到“将 varchar 值“HOME”转换为数据类型 int 时转换失败的错误,我为含糊而道歉,我不确定所有信息会有所帮助,尤其是在不了解数据库的情况下,我有一些 SQL 背景但是我还不是其中的大师...
  • 啊,听起来问题是您的年份并不总是有人。查看更新。
猜你喜欢
  • 2021-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-26
  • 1970-01-01
  • 2013-10-17
  • 1970-01-01
  • 2013-03-19
相关资源
最近更新 更多