Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 如何从列中提取值并在另一列中更新结果_Sql_Sql Server_Split - Fatal编程技术网

Sql 如何从列中提取值并在另一列中更新结果

Sql 如何从列中提取值并在另一列中更新结果,sql,sql-server,split,Sql,Sql Server,Split,我有这张桌子: 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 2

我有这张桌子:

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... )
第1个编号从编号1中提取
第二个数字是从年份中提取的
第三个数字从月份中提取(将一月转换为01)
第四个数字从天中提取(如果天<10,则在开始处加0:01,02…)
用于执行以下操作

  • 获取
    和其后第一个空格之间的字符
  • 获取最后4个字符
  • 使用大小写表达式根据与字符串类似的月份名称生成月份号
  • 获取逗号前的2个字符,并将其中的任何空白字符替换为
    0
  • 并将这4个值连接在一起。

    从Nº1中提取第一个数字
    第二个数字是从年份中提取的
    第三个数字从月份中提取(将一月转换为01)
    第四个数字从天中提取(如果天<10,则在开始处加0:01,02…)
    
    用于执行以下操作

  • 获取
    和其后第一个空格之间的字符
  • 获取最后4个字符
  • 使用大小写表达式根据与字符串类似的月份名称生成月份号
  • 获取逗号前的2个字符,并将其中的任何空白字符替换为
    0

  • 并将这4个值连接在一起。

    如果对辅助表值函数打开:

    示例

    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将返回

    IDDate      FullDate
    120140104   Nº1 (26) - Friday 4, January 2014
    220150210   Nº2 (64) - Monday 10, February 2015
    

    感兴趣的功能

    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 
    )
    

    如果对辅助表值函数打开:

    示例

    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将返回

    IDDate      FullDate
    120140104   Nº1 (26) - Friday 4, January 2014
    220150210   Nº2 (64) - Monday 10, February 2015
    

    感兴趣的功能

    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 
    )
    

    如果您必须在不使用像John Poster这样的函数的情况下解决这个问题(我也会这么做),那么您可以深入研究并开始一条噩梦般的字符串函数路径。挑战在于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
    

    然后去问问决定这样存储数据的人他们为什么这么做?这根本不是处理数据的方法。

    如果您必须在不使用John Poster这样的函数的情况下解决这个问题(我会这么做),您可以深入研究并开始一条噩梦般的字符串函数路径。挑战在于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
    

    然后去问问决定这样存储数据的人他们为什么这么做?这根本不是处理数据的方法。

    这将提取日期值。它只是查找逗号,备份几个字符并获取日期,去掉逗号并将其视为军事日期

    select convert(date,  
       replace(substring(FullDate, charindex(',', FullDate) - 2, 100), ',', ''), 106)
    

    使用
    format()
    或日期样式112获得所需的输出。第一个字符显然只是
    子字符串(FullDate,3,1)
    ,因此只需将其附加到前面。

    这将提取一个日期值。它只是查找逗号,备份几个字符并获取日期,去掉逗号并将其视为军事日期

    select convert(date,  
       replace(substring(FullDate, charindex(',', FullDate) - 2, 100), ',', ''), 106)
    


    使用
    format()
    或日期样式112获得所需的输出。第一个字符显然只是
    子字符串(FullDate,3,1)
    ,因此只需将其附加到前面。

    问题的根源在于将日期存储为字符串。数据类型的存在是有原因的,不要对自己这样做。是的,我知道。但我别无选择。当我得到新的IdDate时,我会删除FullDate列。你能分享一些实际的样本数据吗?这意味着一个CREATETABLE脚本,后跟几个insert语句。哦,天哪……我想你的专栏里其实有那么多多余的垃圾???废话???哦,不。共享表脚本问题的根源是您将日期存储为字符串。数据类型的存在是有原因的,不要对自己这样做。是的,我知道。但我别无选择。当我得到新的IdDate时,我会删除FullDate列。你能分享一些实际的样本数据吗?这意味着一个CREATETABLE脚本,后跟几个insert语句。哦,天哪……我想你的专栏里其实有那么多多余的垃圾???废话???哦,不,共享桌子,但我怎么能做到呢?(也添加到了答案中)。你问了一个广泛的问题,我给了你一个广泛的策略。使用此链接进行一些研究并尝试解决问题。如果你被这些技巧中的任何一种卡住了,那就把它变成一个新问题,这样你就可以把你的问题集中在一种特定的技巧上。我不同意。OP不知道该怎么办。他们提供了功能ddl和示例数据。很明显,他们期望的产出是什么。这些数据是如此完整的火车残骸,要解开这团乱麻并不容易。但我怎么能做到呢?(也添加到了答案中)。你问了一个广泛的问题,我给了你一个广泛的策略。使用此链接进行一些研究并尝试解决问题。如果你被这些技巧中的任何一种卡住了,那就把它变成一个新问题,这样你就可以把你的问题集中在一种特定的技巧上。我不同意。OP不知道该怎么办。他们提供了功能ddl和示例数据。很明显,他们期望的产出是什么。这些数据是如此完整的火车残骸,不容易解开这些混乱。更干净+1多干净啊+1感谢您的回复,但当我运行您的代码时,请显示IdDate=Null。它不像你的screenshot@RaulEscalona如果转换失败,try_convert()将返回NULL。拼写错误的日期?额外的空间?像6月31日这样的假日期?我只是复制并粘贴你的第一个代码。展示Null@RaulEs