Combinar dos campos en uno con sólo los elementos nuevos
-
28-09-2019 - |
Pregunta
Tengo dos tablas que ambos contienen 'tubería valores separó'
por ejemplo:
Tabla 1:
DataField_A
item 1|item 2|item 3|etc.....
Tabla 2:
DataField_A
item 7|item 5|item 3|etc.....
Necesito combinar la Tabla 2 en la tabla 1 de tal manera que la tabla 2 contiene todos los artículos a través de ambas tablas.
Hacer esto pro-gramaticalmente sería una simple cuestión de bucle a través de cada elemento en la tabla 2 y la adición a la tabla 1 si no existe en la tabla 1.
¿Cómo se puede hacer esto en SQL como un procedimiento almacenado?
Solución
He utilizado una función de análisis (el ejemplo estoy usando viene de aquí ) para analizar la cadena en la Tabla 1. Luego utilizo esa función en un CTE para encontrar los elementos que faltan en la Tabla2 y combinar los datos.
/* Helper function to parse delimited string */
CREATE FUNCTION [dbo].[fnParseStringTSQL] (@string NVARCHAR(MAX),@separator NCHAR(1))
RETURNS @parsedString TABLE (string NVARCHAR(MAX))
AS
BEGIN
DECLARE @position int
SET @position = 1
SET @string = @string + @separator
WHILE charindex(@separator,@string,@position) <> 0
BEGIN
INSERT into @parsedString
SELECT substring(@string, @position, charindex(@separator,@string,@position) - @position)
SET @position = charindex(@separator,@string,@position) + 1
END
RETURN
END
go
/* Set up some sample data */
declare @Table1 table (
id int,
DataField_1A varchar(500)
)
declare @Table2 table (
id int,
DataField_2A varchar(500)
)
insert into @Table1
(id, DataField_1A)
select 1, 'item 1|item 2|item 3'
union
select 2, 'item A|item B|item C|item D|item Z'
insert into @Table2
(id, DataField_2A)
select 1, 'item 7|item 5|item 3'
union
select 2, 'item A|item Y|item Z'
/* data before the update */
select * from @Table2
/* boolean to ensure loop executes at least once */
declare @FirstLoop bit
set @FirstLoop = 1
/* Do the updates */
while (@FirstLoop = 1 or @@ROWCOUNT <> 0) begin
set @FirstLoop = 0
;with cteMissingItems as (
select t2.id, p.string
from @Table2 t2
inner join @Table1 t1
on t2.id = t1.id
cross apply dbo.fnParseStringTSQL(t1.DataField_1A,'|') p
where charindex(p.string, t2.DataField_2A) = 0
)
update t2
set t2.DataField_2A = t2.DataField_2A + '|' + mi.string
from @Table2 t2
inner join cteMissingItems mi
on t2.id = mi.id
end /* while */
/* Prove the update worked */
select * from @Table2
/* Clean up */
drop function dbo.fnParseStringTSQL
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow