MySQL从一个表中减去第二个表中某些行的值

时间:2013-12-26 10:23:02

标签: mysql sql sql-update inner-join

我有2张桌子 播放器:

| ID | PLAYER | WARNINGS |
|----|--------|----------|
|  1 |      a |       35 |
|  2 |      b |       70 |
|  3 |      c |       65 |

警告:

| ID | PLAYER | POWER | ACTIVE |       TIMEEND |
|----|--------|-------|--------|---------------|
|  1 |      a |     5 |      1 | 1388051312120 |
|  2 |      a |    10 |      1 | 1388051312120 |
|  3 |      a |    20 |      1 | 1388051312120 |
|  4 |      b |    30 |      1 | 1388051312120 |
|  5 |      b |    40 |      1 | 1388051312120 |
|  6 |      c |    10 |      1 | 1388051312120 |
|  7 |      c |    55 |      1 | 1388051312120 |

我想检查warns warns.active=1所在的每一行,然后warns.timeend <= NOW()warns.power players.warnings删除(减去)player并更改warns.active=2

因此,表格必须如下所示:

播放器:

| ID | PLAYER | WARNINGS |
|----|--------|----------|
|  1 |      a |        0 |
|  2 |      b |        0 |
|  3 |      c |        0 |

警告:

| ID | PLAYER | POWER | ACTIVE |       TIMEEND |
|----|--------|-------|--------|---------------|
|  1 |      a |     5 |      2 | 1388051312120 |
|  2 |      a |    10 |      2 | 1388051312120 |
|  3 |      a |    20 |      2 | 1388051312120 |
|  4 |      b |    30 |      2 | 1388051312120 |
|  5 |      b |    40 |      2 | 1388051312120 |
|  6 |      c |    10 |      2 | 1388051312120 |
|  7 |      c |    55 |      2 | 1388051312120 |

我只有那个: UPDATE players,warns SET warns.Active=2, players.Warnings=players.Warnings-warns.Power WHERE (warns.Active=1) AND (warns.TimeEnd <= NOW()) AND (warns.Player=players.Player); 但那给了我:

播放器:

| ID | PLAYER | WARNINGS |
|----|--------|----------|
|  1 |      a |       30 |
|  2 |      b |       40 |
|  3 |      c |       55 |

警告:

| ID | PLAYER | POWER | ACTIVE |       TIMEEND |
|----|--------|-------|--------|---------------|
|  1 |      a |     5 |      2 | 1388051312120 |
|  2 |      a |    10 |      2 | 1388051312120 |
|  3 |      a |    20 |      2 | 1388051312120 |
|  4 |      b |    30 |      2 | 1388051312120 |
|  5 |      b |    40 |      2 | 1388051312120 |
|  6 |      c |    10 |      2 | 1388051312120 |
|  7 |      c |    55 |      2 | 1388051312120 |

所以只减去每个玩家的第一行...... 任何想法如何解决? 抱歉我的英语不好!我希望你理解我:)。

2 个答案:

答案 0 :(得分:2)

试试这个:

UPDATE players P 
INNER JOIN (SELECT W.PLAYER, SUM(W.POWER) WARNING
            FROM WARNS W WHERE W.active = 1 AND W.timeend <= NOW()
            GROUP BY W.PLAYER 
           ) A ON P.PLAYER = A.PLAYER
SET P.WARNINGS = P.WARNINGS - A.WARNING ;

UPDATE WARNS 
SET active = 2
WHERE active = 1 AND timeend <= NOW();

答案 1 :(得分:0)

SQLite只是一次更新一个表。

BEGIN;
UPDATE players SET warnings=warnings - (SELECT SUM(power) FROM warns WHERE id=players.id AND DATETIME(??? TimeEnd ???) <= DATETIME('NOW') AND active=1);
UPDATE warns SET active=2 WHERE DATETIME(??? TimeEnd ???) <= DATETIME('NOW') AND active=1;
COMMIT;

这是什么类型的TimeEnd

但是,我建议你采用另一种方法(没有冗余数据):

TABLE: players (ID, Player);
TABLE: warns (ID, POWER, TIMEEND);
VIEW: active_warnings = SELECT ID, Player, COALESCE(SUM(Power),0)
                        FROM Player
                        LEFT JOIN warns USING(ID)
                        WHERE DATETIME(??? TimeEnd ???) <= DATETIME('NOW')
                        GROUP BY Id;