3

我有一个逗号分隔的字符串,如下所示:

key1=value1,key2=value2,key3=value3,key1=value1.1,key2=value2.1,key3=value3.1

我想把它解析成一个看起来像这样的表:

Key1       Key2       Key3
==============================
value1     value2     value3
value1.1   value2.1   value3.1

我能够将字符串拆分为行:

ID      Data
================
1       key1=value1
2       key2=value2
3       key3=value3
...

但我被困在那里,似乎无法找到解决其余部分的方法。任何帮助表示赞赏。

4

4 回答 4

0

这是一个更通用的版本,不依赖于顺序 ID。但是,尚不清楚如何说value1,value2在您的最终结果中彼此相关,而不是value1, value2.1。在这个解决方案中,我任意对给定键的每次出现进行排序。

With SplitKeyValuePairs As
    (
    Select Id
        , Left([Data], CharIndex('=', [Data]) - 1) As KeyName
        , Substring([Data], CharIndex('=', [Data]) + 1, Len([Data])) As Value
        , Row_Number() Over ( Partition By Left([Data], CharIndex('=', [Data]) - 1) Order By Id ) As RowNum
    From SplitDelimitedString
    )
Select Max ( Case When KeyName = 'Key1' Then Value End ) As [Key1]
    , Max ( Case When KeyName = 'Key2' Then Value End ) As [Key2]
    , Max ( Case When KeyName = 'Key3' Then Value End ) As [Key3]
From SplitKeyValuePairs
Group By RowNum

SQL 小提琴版本

于 2013-05-22T21:33:57.497 回答
0

如果您能够将数据放入每行格式的一个键/值对中,那么大部分工作就完成了。让我称之为结果t。这样的事情可能会让你走完剩下的路:

select max(case when LEFT(data, 4) = 'key1' then SUBSTRING(data, 6, len(data)) end) as key1,
       MAX(case when LEFT(data, 4) = 'key2' then SUBSTRING(data, 6, len(data)) end) as key2,
       MAX(case when LEFT(data, 4) = 'key2' then SUBSTRING(data, 6, len(data)) end) as key3
from t
group by (id - 1)/3

这假设id按顺序分配 ,如您的示例所示。

于 2013-05-22T21:18:56.940 回答
0

这也应该有效:

SELECT *
FROM
   (
      SELECT
         Grp = ID / 3,
         KeyName = Left(Data, CharIndex('=', Data) - 1),
         Value = Substring(Data, CharIndex('=', Data) + 1, 8000)
      FROM
         SplitString
   ) S
   PIVOT (Max(Value) FOR KeyName IN (Key1, Key2, Key3)) P
于 2013-05-22T21:40:43.960 回答
0

我知道这篇文章真的很老了,但把它留在这里以防万一有人发现这对他们的特定解析要求有用或适合。

-- =============================================
-- Author:	Peter Gumpal
-- Create date: October 23, 2018
-- Description:	This function was developed to transform a key-value pair delimited string into a table.
--usage as follows:
-- Select * from dbo.KVParser('LP=pH FM=(begin)[odor](add)[odor](end) US=pgumpal')
-- this will return 3 records containing keys: LP, FM and US. Between "=" are values so  if the string
-- used is a CSV, the comma character will not be omitted. 
-- Key limitation: Fixed to two characters, update code as required.
-- Note: Code not optimal, suggestions/mods are always welcome. - Peter :)
-- =============================================
CREATE FUNCTION [dbo].[KVParser] 
(
@pKVString varchar(500)
)
RETURNS  @kvtemp table ([key] varchar(2), [val] varchar(300))
AS
Begin
Declare @str varchar(500)

set @str = @pKVString -- 'LP=pH FM=(begin)[odor](add)[odor](end) US=pgumpal'
Declare @curKey varchar(2)
Declare @curChar varchar(1)
Declare @concatStr varchar(300)
Declare @ctrI int
Set @ctrI = 0
While (len(@str) > @ctrI)
Begin
	Set @curChar = SUBSTRING(@str,@ctrI,1)
	If (@curChar = '=')
		Begin
			Set @curKey = SUBSTRING(@str, @ctrI - 2 ,2) --get the key
				--begin, get value from its right side
				Set @ctrI = @ctrI + 1
				Set @curChar = SUBSTRING(@str,@ctrI,1)
				Set @concatStr = ''
				--loop into the value
				While (@curChar <> '='AND len(@str)  >= @ctrI)
					Begin
						Set @curChar = SUBSTRING(@str,@ctrI,1)
						Set @concatStr = isnull(@concatStr,'') + ISNULL(@curChar,'')
						Set @ctrI = @ctrI + 1
					End
			    --end, get value from its right side

			Insert into @kvtemp([key],[val])
				Select @curKey, LEFT(@concatStr, IIF(RIGHT(@concatStr,1)= '=', len(@concatStr)-3,len(@concatStr)))
				--above IIF was added to trim the closing key and = / line needs improvement. 
			Set @ctrI = @ctrI - 3 --decrement counter to 3 to back read the key for the closing =
		End
	Set @ctrI = @ctrI + 1
End
Return
End

于 2018-10-22T10:46:12.453 回答