SCHL Script Patindex
-
17-09-2020 - |
Pregunta
Creo que tengo un error de sintaxis en mi script, pero no puedo averiguar dónde.
¡Quiero seleccionar el entero que cae entre un par de () que comienza desde la derecha de una celda?Razón, puede haber otro par de soportes que contengan personajes
y qué pasaría algunos registros w / o cierres paréntesis por alguna razón ...
e.g.
Period | ProgrammeName |
Jan | ABC (Children) (30) |
Feb | Helloworld (20T (20) |
Resultado: 30 20
select
Period,
ProgrammeName,
substring(ProgrammeName,(len(ProgrammeName) - (patindex('%(%', Reverse(ProgrammeName)))+2),(len(ProgrammeName)-1))
from
Table
pero solo muestra
30)
20)
Lo he estado manipulando para que no extraiga ')', pero no puede obtener los resultados esperados.
Solución
Entonces, ¿debe agarrar lo que sea entre el conjunto final de soportes abiertos y de cierre al final de una cadena, derecho?
En primer lugar, encuentre el primer soporte de apertura desde el extremo de la cadena. Yo usaría chardex, ya que estás buscando un solo carácter; No necesitas usar el papeleo.
SELECT LEN(ProgrammeName) + 1 - CHARINDEX('(', REVERSE(ProgrammeName)) FROM Table
Luego, encuentre el primer soporte de cierre desde el extremo de la cadena:
SELECT LEN(ProgrammeName) + 1 - CHARINDEX(')', REVERSE(ProgrammeName)) FROM Table
entonces, ponlos juntos. Para usar la subcadena, necesita la posición del primer carácter, luego la longitud de la cadena que desea, por lo que necesita el primer resultado (la posición del '('), y luego el segundo resultado menos el primer resultado, para obtener la longitud del bit cortenido, como punto de partida:
SELECT (LEN(ProgrammeName) + 1 - CHARINDEX(')', REVERSE(ProgrammeName))) - (LEN(ProgrammeName) + 1 - CHARINDEX('(', REVERSE(ProgrammeName))) FROM Table
También debe hacer un poco de jugueteo para extraer la parte entre los soportes, dejando los soportes solos. Eso se explica en los comentarios en este ejemplo final, donde la expresión final debe estar haciendo el trabajo que desea:
SELECT
-- Position of first bracket
LEN(ProgrammeName) + 1 - CHARINDEX('(', REVERSE(ProgrammeName)),
-- Position of second bracket
LEN(ProgrammeName) + 1 - CHARINDEX(')', REVERSE(ProgrammeName)),
-- Position of second bracket minus position of first bracket gives length
(LEN(ProgrammeName) + 1 - CHARINDEX(')', REVERSE(ProgrammeName))) - (LEN(ProgrammeName) + 1 - CHARINDEX('(', REVERSE(ProgrammeName))),
-- If we want to extract the bit between the brackets, we need to start from the bracket position
-- plus one character, and knock one off the length, to avoid grabbing the closing bracket.
SUBSTRING(ProgrammeName, 1 + LEN(ProgrammeName) + 1 - CHARINDEX('(', REVERSE(ProgrammeName)), (LEN(ProgrammeName) + 1 - CHARINDEX(')', REVERSE(ProgrammeName))) - (LEN(ProgrammeName) + 1 - CHARINDEX('(', REVERSE(ProgrammeName))) - 1)
FROM
Table
He roto mi respuesta para que pueda ver cómo me acerco a los problemas como estos: hágalos un poco a la vez, revisando los resultados a medida que avanza, y es más fácil obtener la cabeza.