使用MySql

时间:2016-04-11 16:07:12

标签: mysql sql-update

使用两个表,一对多关系,我需要更新所有子条目的最强状态的父表。根据表2中的条目,Table1的结果应如下所示:

                  +-----------------------+    +-----------------------+
                  | 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用于任何大于2的项,但是保留0或1。 MySQL的这个有点超出了我的想法。

2 个答案:

答案 0 :(得分:1)

如果0-1-2是订单会更简单,因为你可以使用单个min()函数。这样你需要在内部稍微调整min()函数以给予数字1不同的权重,你需要用另一个case表达式来解释设置部分中的结果:

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

答案 1 :(得分: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(2)的排序方式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

但是如果我们想在没有子查询的MAX语句中使用MINGROUP BY,则该函数必须是可逆的。所以我们还需要一个函数 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 “旋转”。 “最强”的数字是 g(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语句中使用它来获得每个项目的“最强”数字。