tutorial - SQL Server 2008 R2: Cadenas coincidentes
sql server 2014 (3)
Tengo la siguiente tabla:
Mesa:
CREATE TABLE str_matching
(
colstr varchar(200)
);
Insertar datos:
INSERT INTO str_matching VALUES(''5sXYZA1010B'')
INSERT INTO str_matching VALUES(''A1010B'')
INSERT INTO str_matching VALUES(''AMZ103B15K'')
INSERT INTO str_matching VALUES(''B15K'')
INSERT INTO str_matching VALUES(''XC101'')
INSERT INTO str_matching VALUES(''C101'')
INSERT INTO str_matching VALUES(''502KMD1FZ10009L'')
INSERT INTO str_matching VALUES(''FZ10009L'')
INSERT INTO str_matching VALUES(''A9L'')
INSERT INTO str_matching VALUES(''XZ049L'')
INSERT INTO str_matching VALUES(''LM101'')
Resultado esperado: Quiero mostrar solo aquellos registros que tienen entradas duplicadas, si una cadena coincide con la última parte de cualquier cadena, entonces estoy considerando como duplicado.
Por ejemplo: tengo dos cuerdas
-
5sXYZA1010B
-
A1010B
Segunda cuerda que coincide al final de la primera cuerda, por lo que desea mostrar dichos registros.
Nota : la longitud de la cadena no es fija, puede coincidir en cualquier punto.
Resultado Esperado:
colstr
--------------------
5sXYZA1010B
A1010B
AMZ103B15K
B15K
XC101
C101
502KMD1FZ10009L
FZ10009L
puede coincidir en cualquier punto.
Para hacer coincidir cualquier punto, utilice like
con comodines ( %
) en cada lado:
Para múltiples coincidencias, agregue distinct
select l.colstr
from str_matching l
inner join str_matching r
on l.colstr<>r.colstr
and (l.colstr like ''%'' + r.colstr +''%''
or r.colstr like ''%'' + l.colstr +''%''
)
demostración de rextester: http://rextester.com/ICIKJ2256
devoluciones:
+-----------------+
| colstr |
+-----------------+
| A1010B |
| 5sXYZA1010B |
| B15K |
| AMZ103B15K |
| C101 |
| XC101 |
| FZ10009L |
| 502KMD1FZ10009L |
+-----------------+
Dada la respuesta de Martin Smith, supongo que malinterpreté tu intento de ''emparejamiento en cualquier punto'', así que para unir el final de la cadena no usarías el + ''%''
posterior
Esto debería hacerlo ( demo )
SELECT DISTINCT CA.colstr
FROM str_matching s1
JOIN str_matching s2
ON s1.colstr <> s2.colstr
AND s2.colstr LIKE ''%'' + s1.colstr
CROSS APPLY (VALUES(s1.colstr),
(s2.colstr)) CA(colstr)
Sin embargo, si str_matching
tiene muchas filas, el rendimiento será pobre. Agregar un índice en el reverso de la cadena puede mejorar sustancialmente las cosas, como en el ejemplo a continuación.
CREATE TABLE str_matching
(
colstr varchar(200),
colstr_rev AS REVERSE(colstr)
);
CREATE INDEX ix_colstr_rev on str_matching(colstr_rev)
SELECT colstr = REVERSE(CA.colstr_rev)
FROM str_matching s1
JOIN str_matching s2
ON s1.colstr_rev <> s2.colstr_rev
AND s2.colstr_rev LIKE s1.colstr_rev + ''%''
CROSS APPLY (VALUES(s1.colstr_rev),
(s2.colstr_rev)) CA(colstr_rev)
GROUP BY CA.colstr_rev
Puedes usarlo.
;WITH CTE AS (
select *,RN = ROW_NUMBER() OVER (ORDER BY LEN(colstr)) from str_matching
)
,CTE2 AS (
SELECT T1.colstr colstr1 ,X.colstr colstr2 FROM CTE T1
CROSS APPLY (SELECT * FROM CTE T2 WHERE T2.RN > T1.RN AND RIGHT(T2.colstr, LEN(T1.colstr)) = T1.colstr) AS X
)
SELECT colstr1 FROM CTE2
UNION ALL
SELECT colstr2 FROM CTE2
Resultado:
5sXYZA1010B
A1010B
AMZ103B15K
B15K
XC101
C101
502KMD1FZ10009L
FZ10009L