【问题标题】:MySQL subtracting value from one table by some rows from second tableMySQL从一张表中减去第二张表中的某些行的值
【发布时间】:2013-12-26 10:23:01
【问题描述】:

我有 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 |

我想检查warnswarns.active=1 的每一行,然后如果warns.timeend <= NOW()players.warningsplayers.warnings 中删除(减去)warns.power 并更改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 |

所以只减去每个玩家的第一行... 任何想法如何解决这个问题? 对不起我的英语不好!希望你能理解我:)

【问题讨论】:

    标签: mysql sql sql-update inner-join


    【解决方案1】:

    试试这个:

    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();
    

    【讨论】:

    • Hyym,不;/玩家a有-135,b有70,c有65。(所以所有分数都从玩家a中减去;/)
    • @user2250333 检查我更新的答案。它将解决您的问题。我忘了把 GROUP BY 放在 INNER QUERY 中
    • 哦!谢谢 :) 效果很好...我必须了解更多关于 SQL 语法的知识... :D 所以谢谢!
    • 嗨,嗨!是否可以获得更改“警告”的玩家列表(结果集)? (我是用 Java 写的)
    【解决方案2】:

    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;
    

    【讨论】:

    • TimeEnd 是来自 java 的时间,以毫秒为单位 - 从 (java) 代码中使用它更容易。
    猜你喜欢
    • 1970-01-01
    • 2023-03-16
    • 1970-01-01
    • 2021-12-03
    • 1970-01-01
    • 1970-01-01
    • 2015-06-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多