2011-12-01 8 views
5

Ok esto es difícil de frase, así que aquí va ...de consultas SQL para actualizar una columna basada en los valores de otras columnas de la misma tabla

estoy usando MS SQL Server 2008 R2. Tengo una tabla temporal que permite decir tiene dos columnas ya pobladas. Hay una tercera columna vacía que quiero completar en función del valor de las dos primeras columnas. Lo que quiero hacer es crear un guid (usando NEWUID()) para cada combinación combinada de col1 y col2. Aquí está un ejemplo visual:

Digamos que tengo una tabla temporal que se parece a este principio:

Name Activity SpecialId 
James Running  
James Running 
James Walking 
John Running 
John Running 
John Walking 

yo quiero que se actualiza con nuevos GUID para que se vea así:

Name Activity SpecialId 
James Running  SOMEFAKEGUID_1 
James Running  SOMEFAKEGUID_1 
James Walking  SOMEFAKEGUID_2 
John Running  SOMEFAKEGUID_3 
John Running  SOMEFAKEGUID_3 
John Walking  SOMEFAKEGUID_4 

Observe cómo se crea un nuevo GUID para cada par coincidente. Así que el combo James/Running tiene el mismo GUID para todos los combos James/Running ... y el John/Running también tiene el mismo GUID para los combos John/Running, pero no el mismo GUID que los combos James/Running.

Traté de hacerlo lo más claro posible, pero espero que no esté tan claro como el barro.

¿Puede alguien mostrarme cómo se vería la consulta SQL para actualizar esa tabla temporal con los GUID correctos?

Gracias de antemano.

Ryan

+0

¿Qué base de datos está utilizando? –

+0

Concat ambos campos no es una solución? – danihp

+0

Estoy usando SQL Server 2008, recién publicado. – Ryan

Respuesta

3

Usando NEWID() seems to be a pain. Utilizándolo, un CTE crea una ID de sperate, por lo que necesita una tabla intermedia.

Declare @Table as table (name varchar(20), activity varchar(20) , SpecialID uniqueidentifier) 
Declare @DistinctTable as table (name varchar(20), activity varchar(20) , SpecialID uniqueidentifier) 

INSERT INTO @Table 
(name, activity) 
values 
('James','Running'),  
('James','Running'), 
('James','Walking'), 
('John','Running'), 
('John','Running'), 
('John','Walking') 



WITH distinctt 
    AS (SELECT DISTINCT name, 
         activity 
     FROM @Table) 
INSERT INTO @DistinctTable 
SELECT name, 
     activity, 
     Newid() 
FROM distinctt 

UPDATE @Table 
SET specialid = dt.specialid 
FROM @Table t 
     INNER JOIN @DistinctTable dt 
     ON t.activity = dt.activity 
      AND t.name = dt.name 

SELECT * FROM @Table 

Produce

name     activity    SpecialID 
-------------------- -------------------- ------------------------------------ 
James    Running    AAA22BC5-51FE-43B3-8CC9-4C4A5B4CC981 
James    Running    AAA22BC5-51FE-43B3-8CC9-4C4A5B4CC981 
James    Walking    1722B76B-5F17-4931-8D7C-2ECADB5A4DFD 
John     Running    FBC1F86B-592D-4D30-ACB3-80DA26B00900 
John     Running    FBC1F86B-592D-4D30-ACB3-80DA26B00900 
John     Walking    84282844-AAFD-45CA-9218-F7933E5102C6 
0

Estoy seguro de que hay mejores maneras de hacer esto, pero se puede intentar lo siguiente:

WITH TableId AS 
(
    SELECT DISTINCT Name, Activity 
    FROM YourTable 
) 

UPDATE A 
SET A.SpecialId = B.SpecialId 
FROM YourTable A 
INNER JOIN (SELECT Name, Activity, NEWID() SpecialId FROM TableId) B 
ON A.Name = B.Name AND A.Activity = B.Activity 
+0

Supongo que no has probado que –

+0

@ConradFrix - Y estarías en lo cierto. De hecho, estoy en una pc sin RDBMS. – Lamak

+0

Intenté al principio lo mismo y no funcionó. Consulte la consulta data.se [Sample for lamak] (http://data.stackexchange.com/stackoverflow/s/2212/sample-for-lamak) –

0

Bueno, sé que no estás usando MySQL, pero esta es la forma en que funcionaría en MySQL (probado)

update temp_table, (
select uuid() as spec_key, name, activity from (
select distinct name, activity from temp_table) as anotherTemp) as anotheranotherTemp 
set specialID = anotheranotherTemp.spec_key 
where temp_table.Activity = anotheranotherTemp.activity 
and temp_table.Name = anotheranotherTemp.name; 

Parece que este funcionaría en SQL 2008 (no probado)

MERGE INTO temp_table AS tt 
    USING  (
    select newId() as spec_key, name, activity from (
    select distinct name, activity from temp_table) as anotherTemp 
     ON anotherTemp.activity  = tt.activity 
     and anotherTemp.name = tt.name 
WHEN MATCHED 
    THEN UPDATE 
    SET  specialID = anotherTemp.spec_key; 

Sin embargo, el rendimiento no sería bueno.

Cuestiones relacionadas