Sql 将varchar转换为日期

Sql 将varchar转换为日期,sql,sql-server,casting,Sql,Sql Server,Casting,我想我已经阅读了关于这个话题的每一篇文章,没有一篇能解决我的问题 首先,我正在使用的数据库将所有日期字段都设置为varchar数据类型,这让我发疯,因为每当我处理任何涉及日期的查询时,我总是必须强制转换或转换 我目前正在处理的查询应该是列出所有有特定诊断的医疗患者的列表,但该诊断必须在特定日期之前给出。这是我得到的 SELECT DISTINCT pd.PatientID, pd.PatientName, pmh.DateOfOnset pmh.Diagnosis

我想我已经阅读了关于这个话题的每一篇文章,没有一篇能解决我的问题

首先,我正在使用的数据库将所有日期字段都设置为varchar数据类型,这让我发疯,因为每当我处理任何涉及日期的查询时,我总是必须强制转换或转换

我目前正在处理的查询应该是列出所有有特定诊断的医疗患者的列表,但该诊断必须在特定日期之前给出。这是我得到的

SELECT DISTINCT
    pd.PatientID,
    pd.PatientName,
    pmh.DateOfOnset
    pmh.DiagnosisCode
FROM PatientDemographic pd JOIN PatientMedicalHistory pmh ON pd.PatientID = pmh.PatientID
WHERE pmh.DiagnosisCode = '401.1'
    AND CAST(pmh.DateOfOnset as Date) > CAST('12/31/2014' as Date)
我收到一个错误,表示从字符串转换日期和/或时间时转换失败。它告诉我错误在第1行,尽管选择了不同的行,所以这并没有真正的帮助,我不确定我需要修复什么

正如我提到的,DateOfOnset字段有一个varchar数据类型,我需要找到2014年12月底之前的任何日期。我试图通过尝试不同的CAST语句组合来纠正这个错误——我甚至尝试在SELECT语句中的date字段中包含一个CAST,但仍然得到相同的错误

我之前正在处理另一个查询,该查询要求我查找特定时间范围内的所有患者预约,对于该查询,我将WHERE子句设置为:

WHERE Cast(VisitDate as Date) BETWEEN CAST('01/01/2014' as Date) AND CAST('12/01/2014' as Date)

…而且效果非常好。由于当前查询的设置方式几乎相同,我不确定为什么会出现转换错误。

您的日期格式错误:

SET DATEFORMAT dmy;
SELECT CAST('12/31/2014' as Date);
--Conversion failed when converting date and/or time from character string.
您可以在执行查询之前将其设置为mdy

SET DATEFORMAT mdy;
SELECT CAST('12/31/2014' as Date);
或与样式101一起使用:

SET DATEFORMAT dmy;
SELECT CONVERT(DATE,'12/31/2014',101)
如果确实需要将日期存储为VARCHAR,请至少使用与区域性无关的类型,如


听起来SQL无法将存储的字符串转换为日期。这可以解释为什么CASTpmh.DateOfOnset as Date失败,而CastVisitDate as Date失败,后者可能没有任何格式错误的日期

最好的解决方案是将表列转换为适当的数据类型。第二种最好的情况是,添加包含适当数据类型的列,并转换数据;您必须修复任何现有的坏数据,并在加载数据时动态转换数据。另一个选项是,添加一个计算列,尽管您会遇到上述无效日期的问题。您有什么版本的SQL?更高版本具有isdate函数,这在这里可能会有所帮助


如果不选择修改表,则可能无法编写必须假定某些数据格式无效的查询。

可能pmh中的日期无效。DateOfOnSet错误发生在第1行,因为第1行是包含错误的语句的开头。运行select语句时出错。可能是区域性问题。12/31可能被解释为31/12我只是不明白为什么我用VisitDate的另一个查询工作得很好,而这一个不行。我一直在使用月-日-年-日期格式,以前从来没有遇到过任何问题。是的,我可能被后一个选项卡住了。数据库连接到医疗记录系统,所有日期都以字符串形式输入,因为它们来自系统中的自由文本字段不知道genius是如何设置的,但它为许多不同表中的大量不良数据打开了大门。我可能只是搜索所有诊断并将结果粘贴到Excel中,然后按2014年及之前的所有内容进行筛选。不是很高效,但也不是浪费时间来解决我无法修复的错误……更新:是的,再次查看后,似乎有相当多的日期是空白的。这可能就是让我搞砸的原因。如果日期为空,你可以忽略它们,或者使用默认的日期值吗?今天,1980年1月1日,或者其他一些日子,我将尝试排除所有空白,看看会发生什么!
SET DATEFORMAT dmy;
SELECT CAST('20140201' as Date);
-- 01.02.2014

SET DATEFORMAT mdy;
SELECT CAST('20140201' as Date)
-- 01.02.2014