在一个字段找到匹配值,即一个由空格分隔

问题描述 投票:1回答:6

在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。

谢谢。

sql sql-server delimited-text
6个回答
2
投票

如果它始终是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 

Online Demo


0
投票

需要拆分数据,给行号,然后进行比较。

架构:

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

0
投票

你的问题有两个部分,第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

见简单substringcharindex可以做的工作。


0
投票

这里是一个更解决了这一点。

我在这个环节(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

希望这将有助于。


0
投票

如果你的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]

0
投票

只是为了好玩,有点疯狂的编码:

RecId   Data
2       1 2 3 3 5
3       1 1 1 1 1
© www.soinside.com 2019 - 2024. All rights reserved.