我有一个包含用〜分隔的连续值组的字段。
57|0|0|2|||~56|0|0|2|||~55|0|0|2|||~54|0|0|3|4|5|~53|0|0|4|||~52|0|0|4|||~51|0|0|2|||~
每个组均以ID开头,例如5个值中的54个跟随符|例如| 0 | 0 | 3 | 4 | 5 |并以〜结尾。 如果我有一个ID,例如如何从末尾选择第三个值ID = 54我想选择3;
任何帮助将不胜感激。
答案 0 :(得分:0)
您可以使用Shuumi中的函数将字符串拆分为行,并使用其他问题的代码将拆分的行拆分为列。然后在表中有数据,就可以正常选择:
;WITH Split_Names (ElementID,Element, xmlname)
AS
(
SELECT ElementID,
Element,
CONVERT(XML,'<Names><name>'
+ REPLACE(Element,'|', '</name><name>') + '</name></Names>') AS xmlname
FROM [dbo].[func_Split] ('57|0|0|2|||~56|0|0|2|||~55|0|0|2|||~54|0|0|3|4|5|~53|0|0|4|||~52|0|0|4|||~51|0|0|2|||~','~')
)
SELECT Element,
xmlname.value('/Names[1]/name[1]','varchar(100)') AS ID,
xmlname.value('/Names[1]/name[2]','varchar(100)') AS Element1,
xmlname.value('/Names[1]/name[3]','varchar(100)') AS Element2,
xmlname.value('/Names[1]/name[4]','varchar(100)') AS Element3,
xmlname.value('/Names[1]/name[5]','varchar(100)') AS Element4,
xmlname.value('/Names[1]/name[6]','varchar(100)') AS Element5
INTO #tmp
FROM Split_Names
SELECT Element3 FROM #tmp WHERE ID = 54
答案 1 :(得分:0)
您可以将字符串转换为xml,然后从中获取元素。
select
split.xmlTable.value('v[1]', 'int') as col1,
split.xmlTable.value('v[4]', 'int') as col4
from (
select cast(('<x><v>' + replace(replace(col, '~', '</v></x><x><v>'), '|', '</v><v>') + '</v></x>') as xml) as xmlValue
from yourtable
) as xmlTable
cross apply xmlValue.nodes ('/x') as split(xmlTable)
where split.xmlTable.value('v[1]', 'int') = 54
在Sqlfiddle上here进行测试
答案 2 :(得分:0)
使用这样的数据模型,您将拥有非常复杂且缓慢的查询。这将解决该问题,我强烈建议您对模型进行修改。
这将解决它:
DECLARE @t TABLE(x varchar(max))
INSERT @t
VALUES
('57|0|0|2|||~56|0|0|2|||~55|0|0|2|||~54|0|0|3|4|5|~53|0|0|4|||~52|0|0|4|||~51|0|0|2|'),
('57|0|0|2|||~56|0|0|2|||~55|0|0|2|||~54|0|0|5|4|5|~53|0|0|4|||~52|0|0|4|||~51|0|0|2|')
DECLARE @pos INT = 3
DECLARE @element INT = 54
;WITH CTE as
(
SELECT t.c.value('.', 'VARCHAR(2000)') substr
FROM (
SELECT x = CAST('<t>' +
REPLACE(REPLACE(x, '|', '/'), '~', '</t><t>') + '</t>' AS XML)
FROM @t
) a
CROSS APPLY x.nodes('/t') t(c)
), CTE2 as
(
SELECT substr
FROM CTE
WHERE
cast(concat('<x>',
REPLACE(substr, '/', '</x><x>'
), '</x>') as xml).value('/x[1]','int') = @element
), CTE3 as
(
SELECT
t.c.value('.', 'int') val,
row_number() over(partition by z order by 1/0) - 1 pos
FROM (
SELECT x = CAST('<t>' +
REPLACE(substr, '/', '</t><t>') + '</t>' AS XML),
row_number() over(order by 1/0) z
FROM CTE2
) a
CROSS APPLY x.nodes('/t') t(c)
)
SELECT val
FROM CTE3
WHERE pos = @pos