小编典典

根据ascii值拆分列

sql

我在包含一个大字符串的表中有一个 文本 字段,我要分离的字符串的每个部分都被一个小方块分开。

搜索时,我发现这可能是一个ascii值,所以我运行了它

ascii(substring(image_data, 18,1))

返回 27

如何根据此ascii值将该字段拆分为单独的字段?

预先感谢克里斯

编辑:当前数据看起来像什么的例子。如果可能的话,将TEXT放在=之前作为标题将非常有用。

ABS_ID = 1234567 PERSON_ID = 1234567 PARTY_ID = ABS_D = 123 ABS_T =
ABS_TYPE_ID = 12345 ABS_ED = 123456

在上面的字段数据示例中,ascii值是空格所在的位置

更新 下面提供的代码非常适合我最初给出的示例。实施它时,我发现审计字符串因ENTITY_NM而不同

这里的例子


阅读 176

收藏
2021-04-14

共1个答案

小编典典

提示:您可能想先阅读“更新3” :-)

最重要的提示:不要以这种格式存储数据。如果您可以更改此设置,那么您确实应该…

现在有一些不同的方法:

(并且有提示3 :-):下次请使用RDBMS进行标记,包括版本。这样可以更轻松地为您提供帮助。少猜测…)

像这样尝试

-首先,我将分隔的空格替换为,从而 模拟了 您的问题27。现在,我们看到了您正在谈论的矩形。

DECLARE @YourString VARCHAR(1000)=REPLACE('ABS_ID=1234567 PERSON_ID=1234567 PARTY_ID= ABS_D=123 ABS_T= ABS_TYPE_ID=12345 ABS_ED=123456',' ',CHAR(27));
SELECT @YourString;

-这是查询(需要v2016 +):

SELECT A.[key] AS Position
      ,LEFT(Fragment,PosEqual-1) AS ValueName
      ,SUBSTRING(Fragment,PosEqual+1,1000) AS ValueContent
FROM OPENJSON(CONCAT('["',REPLACE(@YourString,CHAR(27),'","'),'"]')) A
CROSS APPLY(SELECT A.[value] AS Fragment
                  ,CHARINDEX('=',A.[value]) AS PosEqual) B;

结果

Position    ValueName   ValueContent
0           ABS_ID      1234567
1           PERSON_ID   1234567
2           PARTY_ID    
3           ABS_D       123
4           ABS_T   
5           ABS_TYPE_ID 12345
6           ABS_ED      123456

简而言之:

STRING_SPLIT()JSON hack更好,因为第一个位置不安全。

使用一些简单的字符串方法,我们可以将您分离的字符串转换为JSON数组。我们使用打开此数组OPENJSON()。此方法将位置返回为key,将片段返回为value

APPLY将搜索的位置=

SELECT将使用的位置读取来自左,分辩部分=

结果是一个经典的EAV列表。

更新:如果您使用v2016以下的版本…

以下查询在原理上类似,但使用XML hack并适用于v2005以下的版本:

SELECT LEFT(C.Fragment,C.PosEqual-1) AS ValueName
      ,SUBSTRING(C.Fragment,C.PosEqual+1,1000) AS ValueContent
FROM (SELECT CAST('<x>'+REPLACE(@YourString,CHAR(27),'</x><x>')+'</x>' AS XML)) A(CastedToXml)
CROSS APPLY A.CastedToXml.nodes('/x') B(xmlFragment)
CROSS APPLY(SELECT B.xmlFragment.value('text()[1]','nvarchar(1000)') AS Fragment
                  ,CHARINDEX('=',B.xmlFragment.value('text()[1]','nvarchar(1000)')) AS PosEqual) C;

更新2:另一种方法

您可以像这样将其拆分为一个:

SELECT CAST('<x><y>' + REPLACE(REPLACE(@YourString,'=','</y><y>'),CHAR(27),'</y></x><x><y>') + '</y></x>' AS XML);

或这个:

SELECT CAST('<x name="' + REPLACE(REPLACE(@YourString,'=','">'),CHAR(27),'</x><x name="') + '</x>' AS XML);

结果是这样的

<x>
  <y>ABS_ID</y>
  <y>1234567</y>
</x>
<x>
  <y>PERSON_ID</y>
  <y>1234567</y>
</x>
<x>
  <y>PARTY_ID</y>
  <y />
</x>
<x>
  <y>ABS_D</y>
  <y>123</y>
</x>
<x>
  <y>ABS_T</y>
  <y />
</x>
<x>
  <y>ABS_TYPE_ID</y>
  <y>12345</y>
</x>
<x>
  <y>ABS_ED</y>
  <y>123456</y>
</x>

或这个:

<x name="ABS_ID">1234567</x>
<x name="PERSON_ID">1234567</x>
<x name="PARTY_ID" />
<x name="ABS_D">123</x>
<x name="ABS_T" />
<x name="ABS_TYPE_ID">12345</x>
<x name="ABS_ED">123456</x>

更新3(这应该放在最上面:-))

这将隐式进行数据透视:

SELECT CastedToXml.value('(/x[@name="ABS_ID"]/text())[1]','bigint') AS ABS_ID
      ,CastedToXml.value('(/x[@name="PERSON_ID"]/text())[1]','bigint') AS PERSON_ID
      ,CastedToXml.value('(/x[@name="PARTY_ID"]/text())[1]','bigint') AS PARTY_ID
      ,CastedToXml.value('(/x[@name="ABS_D"]/text())[1]','bigint') AS ABS_D
      ,CastedToXml.value('(/x[@name="ABS_T"]/text())[1]','bigint') AS ABS_T
      ,CastedToXml.value('(/x[@name="ABS_TYPE_ID"]/text())[1]','bigint') AS ABS_TYPE_ID
      ,CastedToXml.value('(/x[@name="ABS_ED"]/text())[1]','bigint') AS ABS_ED
FROM
(SELECT CAST('<x name="' + REPLACE(REPLACE(@YourString,'=','">'),CHAR(27),'</x><x name="') + '</x>' AS XML)) A(CastedToXml);

结果

ABS_ID  PERSON_ID   PARTY_ID    ABS_D   ABS_T   ABS_TYPE_ID ABS_ED
1234567 1234567     NULL        123     NULL    12345       123456
2021-04-14