2016-09-16 36 views
9

Jest to podzbiór danych mam:zaktualizować wiele sekund identyfikatorów, aby dopasować pierwsze identyfikatory z serii

|Id1|Id2| 
--------- 
|100| 90| 
|101| 90| 
|102| 90| 
|217|101| 
|218|101| 
|219|101| 

Ale Id2 powinien pasować pierwsze wystąpienie każdego odrębnego wystąpienia ID1, gdy zmiany ID2, jak to:

|Id1|Id2| 
--------- 
|100|100| 
|101|100| 
|102|100| 
|217|217| 
|218|217| 
|219|217| 

Jak mogę to zmienić w tysiącach wierszy z instrukcją aktualizacji?

Dzięki za pomoc, trudno to było wyjaśnić!

+0

Co DBMS używasz? (Serwer SQL? MySQL? Oracle? Coś jeszcze?) – Siyual

+0

Przepraszam, zaktualizowałem tagi, używam serwera SQL. –

Odpowiedz

9

Można użyć CTE z wykorzystaniem FIRST_VALUE:

;WITH ToUpdate AS (
    SELECT Id1, Id2, 
      FIRST_VALUE(Id1) OVER (PARTITION BY Id2 ORDER BY Id1) AS newValue 
    FROM mytable 
) 
UPDATE ToUpdate 
SET Id2 = newValue 

No niestety FIRST_VALUE nie jest dostępna w SQL Server 2008. W tym przypadku można użyć następującego zapytania:

;WITH CTE_Rn AS (
    SELECT Id1, Id2, 
      ROW_NUMBER() OVER (PARTITION BY Id2 ORDER BY Id1) AS rn 
    FROM mytable 
), ToUpdate AS (
    SELECT t1.Id1, t2.Id2, t2.Id1 AS newValue 
    FROM mytable AS t1 
    JOIN CTE_Rn AS t2 ON t1.Id2 = t2.Id2 AND t2.rn = 1 
) 
UPDATE ToUpdate 
SET Id2 = newValue 
+0

Działa to świetnie na nowym serwerze programistycznym z nowym serwerem SQL, ponieważ mogę używać FIRST_VALUE. Niestety, alternatywa działa, ale nie aktualizuje wartości. –

+0

@Fizzgig Testowałem to przed opublikowaniem. Czy możesz dodać przypadek testowy, aby móc odtworzyć otrzymany błąd? –

+0

Jakie informacje są potrzebne? (Przepraszam, jestem tutaj nowy) –