我有一个查询,它通过子串从一个大的存储字段中获取yyyy-MM-dd格式,因此该值自动为varchar.下面是整个记录内容的示例:

EmployeeName$Test User
Email$test@test.com
ADUsername$tuser
TermDate$2023-07-13
EmployeeNumber$12345
Department$Tech

以下SQL查询正确运行并返回所有数据,其中TermDateString从不为空,并且格式似乎始终正确:

with cte as (
    select i.IncidentNumber,
    case when charindex('TermDate$',i.symptom) = 0 or charindex('EmployeeNumber$',i.symptom) = 0 then null else
    substring(symptom,charindex('TermDate$',i.symptom) + 9,(charindex('EmployeeNumber$',i.symptom) - 2) - (charindex('TermDate$',i.symptom) + 9)) 
    end as 'TermDateString'
    from Incident i
    inner join task t on t.parentlink_recid = i.recid
    where i.subject like '%term in proc%'
    and i.status not in ('closed','cancelled','resolved')
    and i.symptom like '%EmployeeName%'
    and t.subject = 'Open WFH Equipment Return Request'
    and t.status not in ('closed','cancelled')
    --and i.incidentnumber = '5305093'
)
select *
--,convert(date,TermDateString,23) 'TermDate'
--,cast(TermDateString as date) 'TermDate'
from cte
--where convert(date,TermDateString,23) > DATEADD(month, -4, GETDATE())
order by incidentnumber desc

Results

但是,我只需要获得TermDateString在特定时间范围内的票证.在将varchar转换为日期或日期时间时,通过取消注释--,convert(date,TermDateString,23) 'TermDate',它总是抛出以下错误: Conversion failed when converting date and/or time from character string.

我认为它与特定记录的数据无关,因为它从不为空,并且我判断了没有前导/尾随空格.此外,我手动测试了多个记录,取消了--and i.incidentnumber = '5305093'的注释,这是第一个结果,也是第二个结果.单独来看,这两种做法都奏效了.但是,当在--and i.incidentnumber = 'xxxx'仍然被注释掉的情况下执行Select top 2 i.incidentnumber时,它会抛出相同的错误,这意味着它只在try 处理多个记录时才会抛出错误.我也try 使用CAST而不是CONVERT,但效果完全相同.

有没有人知道有什么办法能让这玩意起作用?

推荐答案

我认为当TermDateString列中存在无效的日期值时,会出现错误"转换失败,当从字符串转换日期和/或时间时".要解决此问题并在特定时间范围内检索票证,您可以按如下方式修改查询:

sql

WITH cte AS (
    SELECT i.IncidentNumber,
    CASE WHEN CHARINDEX('TermDate$', i.symptom) = 0 OR CHARINDEX('EmployeeNumber$', i.symptom) = 0 THEN NULL ELSE
    SUBSTRING(symptom, CHARINDEX('TermDate$', i.symptom) + 9, (CHARINDEX('EmployeeNumber$', i.symptom) - 2) - (CHARINDEX('TermDate$', i.symptom) + 9)) 
    END AS 'TermDateString'
    FROM Incident i
    INNER JOIN task t ON t.parentlink_recid = i.recid
    WHERE i.subject LIKE '%term in proc%'
    AND i.status NOT IN ('closed', 'cancelled', 'resolved')
    AND i.symptom LIKE '%EmployeeName%'
    AND t.subject = 'Open WFH Equipment Return Request'
    AND t.status NOT IN ('closed', 'cancelled')
)
SELECT *
FROM cte
WHERE TRY_CONVERT(date, TermDateString) BETWEEN '2021-01-01' AND '2021-12-31'
ORDER BY IncidentNumber DESC;
```

在这个修改后的版本中,我将转换函数替换为TRY_CONVERT(date, TermDateString),它可以优雅地处理任何无效的日期值,并返回NULL,而不是抛出错误.此外,我添加了一个BETWEEN条件来过滤所需时间范围内的TermDateString个值(在本例中,从2021年1月1日到2021年12月31日).您可以根据需要调整日期范围.

通过使用TRY_CONVERTBETWEEN条件,查询应该会成功执行,在指定的时间范围内检索票证,不会遇到任何转换错误.

Sql相关问答推荐

Postgresql在加入时显示重复的行

在数据分区内执行确定

更新在两个或多个面中具有交点的面

SQL查询每个客户的最新条目

PostgreSQL 9.6嵌套的INSERT/RETURN语句的CTE性能低得令人无法接受

过go 四周未填充的数据,即W50,51,52-SQL

如何为该查询编写正确分区依据

在WHERE EXISTS子查询中,列返回是否重要?

如何解决错误;ORA-00911:无效字符;在果朗?

DB2 SQL查询结果多余数据

如何用SQL组合客户拥有的产品

SQL Server中使用min()和max()从选定的特定值id表中删除不必要的时间

SQL获取两个日期范围之间的计数

在多个表上递归查找

我如何编写一个遍历数组数组并将所有值连接成一个字符串的 postgres 函数

如果 SQL 中不存在数据,如何根据某个 ID 为所有日期添加前一行

基于源表的 SQL INSERT、UPDATE 和 DELETE

如何通过子 Select 在一次更新(并行数组)中多次更新相同的行

SQL查询以获取从特定可变日期看到的用户

将单行中的多个行值转换为列