【问题标题】:How can I parse a varchar string into three columns, Year, Month and Day如何将 varchar 字符串解析为三列,年、月和日
【发布时间】:2014-09-08 17:17:31
【问题描述】:

我想出一种解决格式不佳的表格的方法是将“日期”列解析为三列,之后我可以正确运行查询。日期格式为 'ddmmmyyyy' 样式 (31DEC2013)。

如何将此字符串解析为三个不同的列“日”、“月”、“年”。

提前致谢

【问题讨论】:

  • 到目前为止没有人提到的一件事是,当您将日期存储在 varchar 字段中时,该字段中出现无效日期的可能性很高。在尝试转换之前,您应该确保所有值都是有效日期。
  • 在 SQL Server 2012 及更高版本中,您可以轻松地使用TRY_CONVERT() 来简单地忽略无法转换的值。在早期版本中,您可能需要首先使用ISDATE() 识别它们,并以某种方式阻止这些行被考虑(一个简单的WHERE 子句通常不足以避免问题)。当然,最好的解决办法是首先停止以这种方式存储这些非日期字符串 - 使用适当的数据类型来存储日期。

标签: sql sql-server parsing


【解决方案1】:

您正试图将数据从一种错误类型转换为另一种错误类型。它是一个日期值,您应该为其使用适当的数据类型,即DATEDATETIME

使用适当的数据类型保存这些数据将使您能够访问许多日期时间函数以进行数据操作。

测试数据

DECLARE @TABLE TABLE(String_Month VARCHAR(9))
INSERT INTO @TABLE VALUES 
 ('31DEC2013')
,('26NOV2013')
,('22SEP2013')
,('31DEC2013')
,('31DEC2013')

查询

SELECT CAST(  CAST(DATEPART(YEAR, String_Month) AS VARCHAR(4))  + '-'
            + CAST(DATEPART(MONTH, String_Month)  AS VARCHAR(2))+ '-'
            + CAST(DATEPART(DAY, String_Month)  AS VARCHAR(2)) AS DATE) AS Result
FROM @TABLE

结果

Result
2013-12-31
2013-11-26
2013-09-22
2013-12-31
2013-12-31

【讨论】:

  • 这绝对比我问的要多!非常感谢你的洞察力。快速提问,有没有办法可以将该查询的结果正确插入到格式化为日期的新列中? @m.ali
  • 如果 DATEPART 能够识别 String_Month 的格式,那么当您可以简单地执行 CAST(String_Month AS date) 时,为什么还要对提取和连接位以及转换结果大惊小怪?
  • @AndriyM 傻我,不知道 SQL Server 将其识别为 DATE :) 感谢您指出这一点 :)
  • 我也不知道,但决定在评论之前检查一下。实际上,我最初会建议这种双重转换:CAST(CAST(String_Month AS datetime) AS date) - 你会同意这仍然会简单得多。
  • Still CAST to datetime 然后我认为 Date 会更好,与我所做的(多个字符串操作)相比:)
【解决方案2】:

试试这个:

select datepart(day, '31DEC2013') as [day], 
       datepart(month, '31DEC2013') as [month],
       datepart(year, '31DEC2013') as [year]

【讨论】:

  • don't use lazy shorthands获取日期部分
  • @Lamak:- 更新了我和 CheeseInPosition 的答案。感谢您的链接:)
【解决方案3】:

DATEPART 命令可以为您做到这一点。例如:

select datepart(day, '31DEC2013')
select datepart(month, '31DEC2013')
select datepart(year, '31DEC2013')

我建议您将日期留在一栏中,并在您的查询中即时使用 datepart。

【讨论】:

  • @midiman 确保您使用的是单引号,而不是双引号。单引号用于字符串。双引号用于列名。
  • don't use lazy shorthands获取日期部分
  • 抱歉,这是我的错误。我没有包括 from 子句!我还在学习,我保证!!非常感谢你,这很有效。
  • 还要确保语言是英语 - 并非所有文化都称十二月为十二月。
【解决方案4】:

由于您将值存储为字符串,因此您需要将其转换为 DataTime,然后使用 DatePart。或者在你的字符串值上使用子字符串

DatePart:

select  datepart(DAY, cast([date] as datetime)) as [day], 
        datepart(MONTH, cast([date] as datetime)) as [month],
        datepart(YEAR, cast([date] as datetime)) as [year]

Substring:

select  SUBSTRING([date], 0, 2) as [day], 
        SUBSTRING([date], 2, 3) as [month],
        SUBSTRING([date], 5, 4) as [year]

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2021-09-15
  • 2022-10-13
  • 1970-01-01
  • 1970-01-01
  • 2020-05-15
  • 1970-01-01
  • 2021-04-16
  • 1970-01-01
相关资源
最近更新 更多