2016-04-11 5 views
3

2つのテーブルを使用して1対多の関係を操作すると、すべての子エントリの最も強いステータスで親テーブルを更新する必要があります。表2のエントリに基づいて、表1の結果は次のようにすべきである: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が最も強い

、及び1 2は、中間で、最も弱いです。

MIN()またはMAX()を使用すること、または各親に対してすべての子エントリを掛けて2を使用することを考えました。そうでない場合は0または1を維持します。このためのMySQLは私の理解を少し超えています。

答えて

1

1つのmin()関数を使用できるため、0-1-2が注文だった方が簡単です。あなたは分を微調整する必要がある。この方法は、()ナンバー1に異なる重みを与えるために内部に少し機能しますが、別のケース式バックセットの一部で結果を解釈する必要があります。

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

ありがとうございます。私は、0,1,2の順番が簡単になることに同意します。しかし、それは既存のシステムで作業することの楽しさです。 – 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

説明:

我々は数値に変換する関数F(N)必要(0、1、2)の方法そのf(0)f(0)f(1)の間である。それを達成するにはいくつかの方法があります。例えばF(N)= ABS(N - 1.1)を変換します:私たちは結果を注文する必要がある場合

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

これはすでに、働くだろう。

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 

しかし、我々はサブクエリなしGROUP BY文でMAXまたはMINを使用したい場合、この関数は可逆的でなければなりません。したがって、関数g(m)g(f(n))= nが必要です。 3つの値しかないので、モジュロ関数を使用して必要な順序になるまで数値を「回転」することができます。我々は参照

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 

F(N)=(N + 2)MOD 3(rotate_2)は、我々が必要関数です。この機能にはMAXを使用できます。元の数に戻すには、
g(m)=(m + 1)mod 3でもう一度「回転」するだけです。 「最強」の数は、グラム(MAX(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 

され、そしてそれは、各項目「最強」の数を取得するGROUP BY文で使用することができます。

+0

トリッキーな解決策!しかし、コードだけでなく、答えにいくつかの背景を提供すればさらに良いでしょう。 – Shadow

+0

今、幸い、@影? :-) –

関連する問題