2016-01-25 7 views
7

mam następujące dwie tabele:SQL: Aktualizacja tabeli poprzez mapowanie dwie kolumny do siebie

 Table A 
+-------------------+ 
|___User___|__Value_| 
| 3  | a  | 
| 4  | b  | 
| 5  | c  | 
|____6_____|__d_____| 



     Table B 
+-------------------+ 
|___User___|__Value_| 
| 1  |  | 
| 4  |  | 
| 5  |  | 
|____9_____|________| 

moim zadaniem jest wziąć user z tabeli A (i ich correspondings value), a następnie map go do tabeli B i wstaw tam te wartości. Tak więc z powyższego przykładu Tabela B powinien wyglądać po uruchomieniu skryptu:

 Table B 
+-------------------+ 
|___User___|__Value_| 
| 1  |  | 
| 4  | b  | 
| 5  | c  | 
|____9_____|________| 

Moje pytanie brzmi: w jaki sposób można skonstruować zapytanie SQL, który zrobi to dla mnie w sposób efektywny, jeśli Tabela A zawiera 300.000 + wpisy i Tabela B zawiera 70 000 wpisów?

UWAGI: W Tabeli A pole User nie jest wyjątkowy i nie jest polem Value. Jednak w Tabeli B zarówno pola User, jak isą unikalne i nie powinny pojawiać się więcej niż jeden raz. Nie są też klucze podstawowe dla obu tabel.

+3

Więc jeśli masz 2 wartości odpowiadające jednemu użytkownikowi na b, która z tych wartości powinna zostać użyta do aktualizacji? – Mihai

+2

Jeśli istnieje więcej niż jeden wiersz dla tego samego "użytkownika" w Tabeli A, "wartość" tego wiersza powinna zostać skopiowana do B? –

+0

Dobre pytanie @AlanHadsell - nie ma znaczenia, który wiersz zostanie skopiowany - może to być zarówno pierwsze zdarzenie, jak i ostatnie z wszystkiego, co znajduje się w kolumnie "wartość" tabeli A – user1775598

Odpowiedz

7

Mogłoby to

update table_b as b 
inner join table_a as a on a.User = b.User 
set b.value = a.value 
0

Twoje pytanie jest jasne, co zrobić z wszelkich wartości, które są już w b. Jeśli używasz left join, to będą one jawnie ustawić na NULL:

update table_b b left join 
     table_a a 
     on a.User = b.User 
    set b.value = a.value; 

Jeśli chcesz zachować istniejące wartości dla niepalących meczów, a następnie użyć inner join.

Należy zauważyć, że może to być nieefektywne, ale powinno być OK, jeśli indeks istnieje na a(user).

Jeśli masz bardzo mało użytkowników w a i wiele i więcej duplikatów, przed połączeniem możesz zsumować a.

+0

Dzięki za szczegółową odpowiedź. Jest około 50 tys. Użytkowników, a tak wiele duplikatów (łącznie 300 wierszy). W żadnej z tabel nie ma obecnie indeksów.Czy mógłbym dodać indeks do tych tabel, czy byłoby to coś, co musiałbym zrobić, gdy tabela została stworzona? Co masz na myśli przez tabelę agregacji a? – user1775598

+0

Najlepszy indeks dla jego tabeli znajduje się na 'table_a (user, value)'. –

1

W rzeczywistych sytuacjach bardziej prawdopodobne jest, że chcesz uzyskać przewidywalną wartość, taką jak największa value dla danego user. W takim przypadku użytkownik będzie potrzebował:

update table_b as b 
inner join (
    select user, max(value) from table_a 
    group by user) as a_max on a.user = b.user 
set b.value = a_max.value