在SQL Server我有一个在它分隔的数据(通过空间)的字段。
EG
recid| Delimited data field
1| 1 2 3 4 5
2| 1 2 3 3 5
3| 1 1 1 1 1
我需要遍历数据库中的所有记录,并询问分隔的数据字段并进行相互比较数据的第三和第四部分,如果它们匹配,返回recid和整个分隔的领域。
所以从我的例子记录2和3匹配数据部分,所以它会返回: -
2|1 2 3 3 5
3|1 1 1 1 1
因为3 3场比赛,象11。
谢谢。
如果它始终是1位和相同的格式,你可以尝试像以下。
select * from @table
where SUBSTRING([data], 5, 1) = SUBSTRING([data], 7, 1)
如果不是(数字不是单一的数字),你可以尝试像以下。
;WITH cte
AS (SELECT F1.recid,
F1.[data],
O.splitdata,
Row_number()
OVER(
partition BY recid
ORDER BY (SELECT 1)) rn
FROM (SELECT *,
Cast('<X>' + Replace(F.data, ' ', '</X><X>') + '</X>' AS
XML)
AS
xmlfilter
FROM @table F)F1
CROSS apply (SELECT fdata.d.value('.', 'varchar(50)') AS
splitdata
FROM f1.xmlfilter.nodes('X') AS fdata(d)) O)
SELECT c1.recid,
c1.data
FROM cte c1
INNER JOIN cte c2
ON c1.recid = c2.recid
AND c1.rn = 3
AND c2.rn = 4
AND c1.splitdata = c2.splitdata
GROUP BY c1.recid,
c1.data
需要拆分数据,给行号,然后进行比较。
架构:
SELECT * INTO #TAB FROM (
SELECT 1, '1 2 3 4 5' UNION ALL
SELECT 2, '1 2 3 3 5' UNION ALL
SELECT 3, '1 1 1 1 1'
)A (recid , Delimited_data_field)
解决方案:
;WITH CTE
AS (
SELECT recid
,Delimited_data_field
,ROW_NUMBER() OVER (PARTITION BY recid ORDER BY (SELECT 1)) RNO
,splt.X.value('.', 'INT') VAL
FROM (
SELECT recid
,Delimited_data_field
,CAST('<M>' + REPLACE(Delimited_data_field, ' ', '</M><M>') + '</M>' AS XML) DATA
FROM #TAB
) A
CROSS APPLY A.DATA.nodes('/M') splt(x)
)
SELECT C.recid
,C2.Delimited_data_field
FROM CTE C
INNER JOIN CTE C2 ON C.recid = C2.recid AND C.RNO = 3 AND C2.RNO = 4
AND C.VAL = C2.VAL
结果:
recid Delimited_data_field
2 1 2 3 3 5
3 1 1 1 1 1
你的问题有两个部分,第n找到拆分,然后进行比较。你的第一个方法应该是,直到你找到建,可以做的工作职能,打破了问题。这里是一个方法内部查询返回结果分裂和外比较后:
SELECT recid,Delimited from (
SELECT recid,Delimited, SUBSTRING(Delimited,
charindex(' ', Delimited, (charindex(' ', Delimited, 1))+2)+1,1)
third, SUBSTRING(Delimited, charindex(' ',Delimited,
(charindex(' ', Delimited, 1))+3)+1,1)
fourth FROM YourTable) tr
WHERE third = fourth
见简单substring
和charindex
可以做的工作。
这里是一个更解决了这一点。
我在这个环节(qazxsw船尾)调整了分裂功能位,使其在您的情况非常有用。
下面是函数。
T-SQL: Opposite to string concatenation - how to split string into multiple records
现在你可以使用这个函数来获取数字的第三和第四的位置,方便地进行比较。
CREATE FUNCTION dbo.SplitAndGetNumberAt (@sep char(1), @s varchar(512), @pos int)
RETURNS INT
BEGIN
declare @val as varchar(10);
WITH Pieces(pn, start, stop) AS (
SELECT 1, 1, CHARINDEX(@sep, @s)
UNION ALL
SELECT pn + 1, stop + 1, CHARINDEX(@sep, @s, stop + 1)
FROM Pieces
WHERE stop > 0
)
SELECT @val = SUBSTRING(@s, start, CASE WHEN stop > 0 THEN stop-start ELSE 512 END)
FROM Pieces where pn = @pos;
RETURN @val
END
希望这将有助于。
如果你的SQL Server 2016或更高版本,您可以使用select recid, deldata
from so1
where dbo.SplitAndGetNumberAt (' ', deldata, 3) = dbo.SplitAndGetNumberAt (' ', deldata, 4)
拆分输入数据尝试一种方法。这里最重要的部分是这样的事实,即当OPENJSON解析JSON阵列中的JSON文本的元素的索引作为键(从0开始)返回。
输入:
OPENJSON()
声明:
CREATE TABLE #Table (
RecId int,
Data varchar(max)
)
INSERT INTO #Table
(RecId, Data)
VALUES
(1, '1 2 3 4 5'),
(2, '1 2 3 3 5'),
(3, '1 1 1 1 1')
输出:
SELECT
t.RecId,
t.Data
FROM #Table t
CROSS APPLY (SELECT [value] FROM OPENJSON('["' + REPLACE(t.Data,' ','","') + '"]') WHERE [key] = 2) j3
CROSS APPLY (SELECT [value] FROM OPENJSON('["' + REPLACE(t.Data,' ','","') + '"]') WHERE [key] = 3) j4
WHERE j3.[value] = j4.[value]
只是为了好玩,有点疯狂的编码:
RecId Data
2 1 2 3 3 5
3 1 1 1 1 1