2016-04-11 24 views
3

kullanarak en güçlü çocuk tablosuyla güncelleştirin İki tabloyla, bire çok ilişkiyle çalışma, üst tabloyu tüm alt girişlerinin en güçlü durumuyla güncelleştirmem gerekiyor. Tablo2 girişleri göre, Tablo1 sonucu, bu gibi olmalıdır:Üst tabloyu, MySql

    +-----------------------+ +-----------------------+ 
        | Table1    | | Table2    | 
        +-----------------------+ +-----------------------+ 
        | table1_id |status1 | | table1_id |status2 | 
        +-----------------------+ +-----------------------+ 
        |0   |1   | |0   |1   | 
        |1   |0   | |0   |1   | 
        |2   |2   | |1   |0   | 
        |3   |0   | |1   |2   | 
        +-----------------------+ |2   |1   | 
               |2   |2   | 
               |3   |1   | 
               |3   |0   | 
               +-----------------------+ 
0 güçlü olduğu

ve 1 ila 2 ortasıdır, zayıf kalmaktadır.

MIN() veya MAX()'u kullanmayı veya hatta her üst öğe için tüm alt girdileri çoğaltmayı ve 2'yi 2'den büyük bir şey için kullanmayı, ancak 0 veya 1'i başka şekilde tutmayı düşündüm. Bunun için MySQL benim kavrayışımın biraz ötesinde.

cevap

1

Tek bir min() işlevi kullanabildiğiniz için, 0-1-2 sipariş verilse daha kolay olurdu. Eğer dk çimdik gerekir Bu şekilde() 1 numaralı farklı ağırlık vermek için içeriden bir nebze işlev ve başka vaka ifade ile geri seti kısmen sonuçları yorumlamak gerekir:

update table1, 
     (select table1_id, min(case status2 when 1 then 3 else status2 end) as status2 
     from table2 
     group by table1_id) t2 
set table1.status1=case t2.status2 when 3 then 1 else status2 end 
where table1.table1_id=t2.table1_id 
+0

Teşekkürler, 0, 1, 2 sırasının daha basit olacağını kabul ediyorum. Bu, mevcut bir sistemle çalışmanın eğlencesidir. – Ricca

1
select t.table1_id, (max((t.status2 + 2) mod 3) + 1) mod 3 as status1 
from Table2 t 
group by t.table1_id 

http://sqlfiddle.com/#!9/8b293/8

Açıklama: bir fonksiyon f ihtiyaç

sayıda dönüştürmek (n) (0, 1, 2) yolu, f (2), f (0) ve f (1) arasında sipariş edilir. Bunu başarmanın çeşitli yolları vardır. örnek f (n) = abs (n - 1.1) dönüştürmek olacaktır:

0 -> 1.1 
1 -> 0.1 
2 -> 0.9 

Bu zaten çalışacak, biz sadece sonuç sipariş gerekiyorsa.

create table t (n int); 
insert into t values (0), (1), (2); 

select n, abs(n - 1.1) 
from t 
order by abs(n - 1.1) desc; 

-- 
n abs(n - 1.1) 
0 1,1 
2 0,9 
1 0,1 

Ama biz alt sorgu olmadan GROUP BY açıklamada MAX veya MIN kullanmak istiyorsanız, fonksiyon geri dönüşümlü olması gerekir. Bu yüzden g (m)g (f (n)) = n numaralı bir işleve ihtiyacımız var. Sadece 3 değere sahip olduğumuz için, gereken sırayı alana kadar sayıları "döndürmek" için modulo işlevini kullanabiliriz.

select n 
    , (n + 1) mod 3 as rotate_1 
    , (n + 2) mod 3 as rotate_2 
    , (n + 3) mod 3 as rotate_3 
from t 

-- 
n rotate_1 rotate_2 rotate_3 
0  1  2  0 
1  2  0  1 
2  0  1  2 

Biz bkz f (n) = (n + 2) mod 3 (rotate_2) ihtiyacımız fonksiyonudur. Bu fonksiyonda MAX'u kullanabiliriz. Orijinal numaraya geri döndürmek için,
g (m) = (m + 1) mod 3 ile bir kez daha "döndürme" yapmamız gerekiyor. "En güçlü" numaralı gr (MAKS (f (n)))

select 
    (MAX((n + 2) mod 3) + 1) mod 3 as strongest, 
    (MIN((n + 2) mod 3) + 1) mod 3 as weakest 
from t 

-- 
strongest weakest 
     0   1 

olurdu Ve bu "güçlü" numaralı Her bir öğeyi almak için GROUP BY açıklamada kullanılabilir.

+0

Zor bir çözüm! Ancak, sadece kod değil, cevaba biraz arka plan sağlamanız daha da iyi olur. – Shadow

+0

Şimdi mutlu, @Shadow? :-) –