【问题标题】:How to PARSE a data string in query?如何在查询中解析数据字符串?
【发布时间】:2014-09-12 22:41:42
【问题描述】:

我有一个表格,其中包含一个客户帐号和 ONE 字段,其中包含多个客户备注。我需要在查询中将客户备注提取到单独的行项目结果中。我在下面包含了我的数据样本和查询的预期输出。

**TABLE**

***Customer #*** ***Customer Notes***
=====================================    
25214 | 05/01/2014 - New Customer setup. - DAB |05/24/2014 - Waive Deposit. - DAB
12254 | 03/15/2013 - VIP customer. - FLH |03/23/2014 - See John if there is a 
        problem with customer's account. - FLH

客户备注数据字段是 TEXT 数据类型。如您所见,对于每个帐号,每个客户都有两个客户备注。我需要解析客户备注数据字段中的数据并得到以下结果:

25214 | 05/01/2014 - New Customer setup. - DAB    
25214 | 05/24/2014 - Waive Deposit. - DAB    
12254 | 03/15/2014 - VIP Customer. - FLH    
12254 | 03/23/2014 - See John if there is a problem with customer's account. - FLH

非常感谢任何帮助!

【问题讨论】:

  • SQL Server 不适合做这样的事情。您在这里使用糟糕的数据库设计,如果可能,您应该重构设计。如果你不这样做,你将继续面临这样的挑战,直到你最终发疯。如果无法重构,请将此数据返回到更适合解析的编程语言。
  • 那个特定的分割函数被称为半字节。它可以工作,但可能是所有不同类型的 t-sql 拆分器中最慢的。它使用了一段时间,也是最糟糕的一种表值函数,多语句版本。您最好在任何地方找到几乎任何其他分离器。

标签: sql-server


【解决方案1】:

如果您无法按照@Abe Miessler 的建议重新设计表格,您可以尝试以下方法。

declare @table as table (AccountNumber int, Notes varchar(4000))

insert into @table values(25214,'|05/01/2014 - New Customer setup. - DAB |05/24/2014 - Waive Deposit. - DAB');
insert into @table values(12254,'|03/15/2013 - VIP customer. - FLH |03/23/2014 - See John if there is a problem with customer''s account. - FLH');

SELECT AccountNumber, Notes.n.value('.','varchar(4000)') as Notes
  FROM (SELECT 
            AccountNumber, 
            CAST(replace(replace(replace((SELECT Notes FOR XML PATH('')),
                     '|','</n><n>|'),
                     '<Notes></n>','<Notes>'),
                     '</Notes>','</n></Notes>') AS XML) AS XNotes
         FROM @table) as t
CROSS APPLY XNotes.nodes('/Notes/n') as Notes(n)

查询将Notes 列转换为 XML,然后使用 T-SQL XML 函数将数据拉入行。


输出

AccountNumber Notes
------------- ----------------------------------------------------------------------------
25214         |05/01/2014 - New Customer setup. - DAB 
25214         |05/24/2014 - Waive Deposit. - DAB
12254         |03/15/2013 - VIP customer. - FLH 
12254         |03/23/2014 - See John if there is a problem with customer's account. - FLH

参考:


编辑: 在 Notes for XML 中正确转义特殊字符。添加了示例输出。

【讨论】:

    【解决方案2】:

    您需要一个唯一的分隔符。我不知道管道是否是您的实际数据的一部分......所以在这个例子中使用日期模式:

    declare @table table (CustID int,Note varchar(max))
    INSERT INTO @table VALUES (25214, '05/01/2014 - New Customer setup. - DAB |05/24/2014 - Waive Deposit. - DAB')
    INSERT INTO @table VALUES (12254, '03/15/2013 - VIP customer. - FLH |03/23/2014 - See John if there is a problem with customer''s account. - FLH')
    
    SELECT CustID,
           left(Note,patindex('%[0-9][0-9]/[0-9][0-9]/[0-9][0-9][0-9][0-9]%', right(Note,len(Note)-1))) as Note
    FROM @table
    
    UNION
    
    SELECT CustID,
           right(Note,len(Note) - patindex('%[0-9][0-9]/[0-9][0-9]/[0-9][0-9][0-9][0-9]%', right(Note,len(Note)-1))) as Note
    FROM @table
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-11
      • 2019-06-21
      • 1970-01-01
      • 2019-05-03
      相关资源
      最近更新 更多