2011-12-01 13 views
5

Ok to jest trudne do wyrażenia, tak tu idzie ...zapytań SQL do aktualizacji kolumny oparte na wartościach innych kolumn w tej samej tabeli

używam MS SQL Server 2008 R2. Mam tabelę tymczasową, która pozwala powiedzieć, że ma dwie już wypełnione kolumny. Istnieje trzecia kolumna pusta, którą chcę wypełnić na podstawie wartości dwóch pierwszych kolumn. Co chcę zrobić, to stworzyć GUID (używając NEWUID()) dla każdego pasującego kombinacja col1 i col2. Oto wizualny przykład:

Powiedzmy Mam temp tabeli, który wygląda tak początkowo:

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

chcę aby uzyskać zaktualizowane o nowe GUID tak, że wygląda tak:

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 

Zobacz, jak tworzony jest nowy identyfikator GUID dla każdej pasującej pary. Tak więc kombinacja James/Running ma taki sam identyfikator GUID dla wszystkich kombinacji James/Running ... i John/Running ma również ten sam identyfikator GUID dla combo John/Running, ale nie taki sam GUID, jak robią to kombinacje James/Running.

Starałem się, aby było to tak jasne, jak to możliwe, ale mam nadzieję, że nie jest to jasne jak błoto!

Czy ktoś może mi pokazać, jak wyglądałoby zapytanie SQL, aby zaktualizować tabelę tymczasową z poprawnymi identyfikatorami GUID?

Z góry dziękuję.

Ryan

+0

Jakiej bazy danych używasz? –

+0

Czy oba pola nie są rozwiązaniem? – danihp

+0

Używam programu SQL Server 2008, właśnie zaktualizowany post. – Ryan

Odpowiedz

3

Korzystanie newID() seems to be a pain. Korzystanie z niego CTE tworzy identyfikator sperate, więc potrzebujesz zamiast tego tabeli pośredniej.

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 

Produkuje

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

Jestem pewien, że są lepsze sposoby, aby to zrobić, ale można spróbować wykonać następujące czynności:

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

Zakładam, że nie przetestowałeś tego –

+0

@ConradFrix - I będziesz absolutnie w porządku. Jestem na komputerze bez RDBMS. – Lamak

+0

Początkowo wypróbowałem to samo i nie zadziałało. Zobacz zapytanie data.se [Sample for lamak] (http://data.stackexchange.com/stackoverflow/s/2212/sample-for-lamak) –

0

Dobrze wiem, że nie używasz MySQL, ale to jest, jak to działa w MySQL (przetestowane)

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; 

wygląda to tak działałby w SQL 2008 (nie testowany)

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; 

Wydajność nie byłaby jednak dobra.

Powiązane problemy