Entiendo que la gente ha hecho esta pregunta de otras maneras antes, pero no estoy interesado en empujar una sola cadena a través de una variable.

Tengo una columna que contiene datos como: QWERTYUIOP-1, QWERTYUIOP-XL, ASDFG-2, HGJFK-SM. La columna se llama producto. Necesito poder extraer texto después del '-' para poder almacenarlo como tamaño en otra columna. para esta instancia llamemos a la tabla productos.

¿Cómo puedes hacer esto en SQL Server? Es bastante simple en postgreSQL con split_part, pero no parece haber una función similar aparte de string_split, y eso solo funciona para tablas. Cuando intento usarlo contra una columna dice que string_split no existe.

¿Alguien puede ayudarme con esto por favor?

0
JK1993 23 jun. 2020 a las 11:44

3 respuestas

La mejor respuesta

Un método es utilizar STUFF para eliminar los caracteres iniciales y utilizar CHARINDEX para encontrar dónde terminan esos caracteres principales:

SELECT V.YourString,
       STUFF(V.YourString,1,CHARINDEX('-',V.YourString),'') AS TrailingCharacters
FROM (VALUES('QWERTYUIOP-1'),('QWERTYUIOP-XL'),('ASDFG-2'),('HGJFK-SM'))V(YourString)

OK, ahora que las publicaciones de meta se han movido. Puede modificar lo anterior para obtener la posición del último carácter - usando REVERSE en su lugar:

SELECT V.YourString,
       STUFF(V.YourString,1,LEN(V.YourString) - CHARINDEX('-',REVERSE(V.YourString))+1,'') AS TrailingCharacters
FROM (VALUES('QWERTYUIOP-1'),('QWERTYUIOP-XL'),('ASDFG-2'),('HGJFK-SM'),('QWER-WETT-EWT-1'))V(YourString)

Alternativamente, puede usar un divisor de cadena como DelimitedSplit8k_LEAD y obtenga la "última" fila:

WITH CTE AS(
    SELECT V.YourString,
           DS.ItemNumber,
           DS.Item,
           ROW_NUMBER() OVER (PARTITION BY V.YourString ORDER BY DS.ItemNumber DESC) AS RN
    FROM (VALUES('QWERTYUIOP-1'),('QWERTYUIOP-XL'),('ASDFG-2'),('HGJFK-SM'),('QWER-WETT-EWT-1'))V(YourString)
         CROSS APPLY dbo.DelimitedSplit8K(V.YourString,'-') DS)
SELECT YourString,
       DS.Item
FROM CTE
WHERE RN = 1;
1
Larnu 23 jun. 2020 a las 09:33
select 
 left(product,charindex('-',product)-1) product_code
 ,right(product,len(product)-charindex('-',product)) product_size
from (values('QWERTYUIOP-1'),('QWERTYUIOP-XL'),('ASDFG-2'),('HGJFK-SM')) p (product)

No use STRING_SPLIT para su propósito, porque la cadena se divide en filas y

Las filas de salida pueden estar en cualquier orden. No se garantiza que el orden coincida con el orden de las subcadenas en la cadena de entrada.

https://docs.microsoft.com/en-us/sql/t-sql/functions/string-split-transact-sql?view=sql-server-ver15

Por lo tanto, nunca sabrá cuál queda (código) y cuál es el correcto (tamaño).

0
shoek 23 jun. 2020 a las 09:25

Puede usar la combinación de String_split y JSON_VALUE para dividir el valor en varias columnas.

DECLARE @productSize table(ProductName VARCHAR(500))
INSERT INTO @productSize values
('QWERTYUIOP-1,QWERTYUIOP-XL, ASDFG-2, HGJFK-SM')

SELECT 
JSON_VALUE(concat('["',replace(value,'-','","'),'"]'),'$[0]') as productname,
JSON_VALUE(concat('["',replace(value,'-','","'),'"]'),'$[1]') as productSize
from @productSize
cross apply STRING_SPLIT(ProductName,',') 
+-------------+-------------+
| productname | productSize |
+-------------+-------------+
| QWERTYUIOP  | 1           |
| QWERTYUIOP  | XL          |
|  ASDFG      | 2           |
|  HGJFK      | SM          |
+-------------+-------------+
1
Venkataraman R 23 jun. 2020 a las 09:09