我有这张桌子:
CREATE TABLE MyTable (
IdDate int,
FullDate varchar(255)
);
insert into MyTable (IdDate,FullDate)
VALUES (0, 'Nº1 (26) - Friday 4, January 2014'),
(0,'Nº2 (64) - Monday 10, February 2015')
我想从FullDate中提取如下内容:
1 2014 01 04
2 2015 02 10
1st number is extracted from Nº1
2nd number is extracted from Year
3rd number is extracted from Month (convert January to 01)
4th number is extracted from day (if day < 10, add 0 at the beginning: 01,02... )
并更新在第一列IdDate中提取的新值
我的最终结果应该是:
IdDate FullDate
120140104 Nº1 (26) - Friday 4, January 2014
220150210 Nº2 (64) - Monday 10, February 2015
答案 0 :(得分:3)
如果对助手表值函数开放:
示例
Declare @YourTable table (IdDate int,FullDate varchar(max))
Insert Into @YourTable values
(0,'Nº1 (26) - Friday 4, January 2014')
,(0,'Nº2 (64) - Monday 10, February 2015')
Update A
set IdDate = substring(Pos1,3,10)
+ try_convert(varchar(10),try_convert(date,Pos6+' '+Pos5+' '+Pos7),112)
From @YourTable A
Cross Apply [dbo].[tvf-Str-Parse-Row](FullDate,' ') B
返回
IDDate FullDate
120140104 Nº1 (26) - Friday 4, January 2014
220150210 Nº2 (64) - Monday 10, February 2015
如果有助于可视化,TVF将返回
感兴趣的功能
CREATE FUNCTION [dbo].[tvf-Str-Parse-Row] (@String varchar(max),@Delimiter varchar(10))
Returns Table
As
Return (
Select Pos1 = ltrim(rtrim(xDim.value('/x[1]','varchar(max)')))
,Pos2 = ltrim(rtrim(xDim.value('/x[2]','varchar(max)')))
,Pos3 = ltrim(rtrim(xDim.value('/x[3]','varchar(max)')))
,Pos4 = ltrim(rtrim(xDim.value('/x[4]','varchar(max)')))
,Pos5 = ltrim(rtrim(xDim.value('/x[5]','varchar(max)')))
,Pos6 = ltrim(rtrim(xDim.value('/x[6]','varchar(max)')))
,Pos7 = ltrim(rtrim(xDim.value('/x[7]','varchar(max)')))
,Pos8 = ltrim(rtrim(xDim.value('/x[8]','varchar(max)')))
,Pos9 = ltrim(rtrim(xDim.value('/x[9]','varchar(max)')))
From (Select Cast('<x>' + replace((Select replace(@String,@Delimiter,'§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' as xml) as xDim) as A
)
或者没有功能
Update A
set IdDate = substring(Pos1,3,10)
+ try_convert(varchar(10),try_convert(date,Pos6+' '+Pos5+' '+Pos7),112)
From @YourTable A
Cross Apply (
Select Pos1 = ltrim(rtrim(xDim.value('/x[1]','varchar(max)')))
,Pos2 = ltrim(rtrim(xDim.value('/x[2]','varchar(max)')))
,Pos3 = ltrim(rtrim(xDim.value('/x[3]','varchar(max)')))
,Pos4 = ltrim(rtrim(xDim.value('/x[4]','varchar(max)')))
,Pos5 = ltrim(rtrim(xDim.value('/x[5]','varchar(max)')))
,Pos6 = ltrim(rtrim(xDim.value('/x[6]','varchar(max)')))
,Pos7 = ltrim(rtrim(xDim.value('/x[7]','varchar(max)')))
From (Select Cast('<x>' + replace((Select replace(FullDate,' ','§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' as xml) as xDim) as A
) B
编辑
这是Shawn的 cleaner 解决方案的扩展版本
Update @YourTable
set IdDate = substring(left(FullDate,charindex(' ',FullDate)-1),3,25)
+try_convert(varchar(10),try_convert(date,replace(substring(FullDate, charindex(',', FullDate) - 2, 100), ',', '')),112)
Select * from @YourTable
答案 1 :(得分:2)
这将提取一个日期值。它只是查找逗号,备份一些字符并获取日期,剥离逗号并将其视为军事日期。
select convert(date,
replace(substring(FullDate, charindex(',', FullDate) - 2, 100), ',', ''), 106)
使用format()
或日期样式112以所需的方式获取输出。第一个字符显然只是substring(FullDate, 3, 1)
,因此只需将其附加到前面即可。
答案 2 :(得分:1)
如果您不必使用像John posted这样的函数(这就是我要做的事情)就可以解决这个问题,则可以深入研究并开始一个字符串函数的噩梦之路。挑战在于t-sql在字符串操作方面并不出色。
这似乎适用于您提供的示例数据。请注意,如果您的数据无法转换为日期,则将失败。
update MyTable
set IdDate = substring(FullDate, 3, CHARINDEX(' ', FullDate) - 3)
+ Right(FullDate, 4)
+ right('0' + convert(varchar(2), datepart(month, convert(date, replace(substring(substring(FullDate, charindex('-', FullDate) + 2, len(FullDate)), charindex(' ', substring(FullDate, charindex('-', FullDate) + 2, len(FullDate))) + 1, len(FullDate)), ',', '')))), 2)
+ right('0' + convert(varchar(2), datepart(day, convert(date, replace(substring(substring(FullDate, charindex('-', FullDate) + 2, len(FullDate)), charindex(' ', substring(FullDate, charindex('-', FullDate) + 2, len(FullDate))) + 1, len(FullDate)), ',', '')))), 2)
select * from MyTable
然后去问决定像这样存储数据的人为什么这么做?这根本不是处理数据的方法。
答案 3 :(得分:0)
1st number is extracted from Nº1
2nd number is extracted from Year
3rd number is extracted from Month (convert January to 01)
4th number is extracted from day (if day < 10, add 0 at the beginning: 01,02... )
使用SQL Server's string functions执行以下操作
Nº
及其后的第一个空格之间的字符。0
替换其中的空白字符。并将这四个值连接在一起。