MySQL通过迭代插入到不同表的信息来更新现有表

MySQL通过迭代插入到不同表的信息来更新现有表,mysql,Mysql,首先,我要指出一个事实,我对MySQL触发器/函数/SP等相当陌生。。。 因此,如果在如何提问这个问题上有任何错误,请让我知道,我将尝试获取我错过的任何信息 我有以下表格: aos_matchs MatchID事件时间联盟初始玩家初始飞机事件目标玩家目标飞机武器命中数msgID aos_玩家MatchID Time纪元VS军备冠军红人蓝人 aos_球员名单姓名ace_因子 aos_matchs.MatchID=aos_players.MatchID MatchID指示 aos_matchs.In

首先,我要指出一个事实,我对MySQL触发器/函数/SP等相当陌生。。。 因此,如果在如何提问这个问题上有任何错误,请让我知道,我将尝试获取我错过的任何信息

我有以下表格: aos_matchs MatchID事件时间联盟初始玩家初始飞机事件目标玩家目标飞机武器命中数msgID

aos_玩家MatchID Time纪元VS军备冠军红人蓝人

aos_球员名单姓名ace_因子

aos_matchs.MatchID=aos_players.MatchID MatchID指示

aos_matchs.Initiator=aos_playerslist.Name由玩家名称链接

aos_matchs.targPlayer=aos_playerslist.Name由玩家名称链接

表示例: aos_匹配:

aos_玩家:

球员

我想用一个触发器捕获插入到匹配表中的任何信息,然后运行一个查询,从MatchInfo表中获取相关信息,并遍历查询结果。 在逐行检查之后,决定后续将更新哪些内容到Players表

我想做的是-

创建一个触发器,用于在插入信息后捕获与表匹配的插入操作

在该触发器中,对相对MatchInfo表运行查询,然后遍历查询结果的每一行,并相应地更新Players表

感谢您对触发示例的任何帮助,该示例将完成上述操作

编辑:根据Barmars的请求,我使用一些原始信息将表格编辑为原始布局,以便更好地理解

aos_播放器列表正在使用以下触发器更新:

DELIMITER $$

USE `mytable`$$

DROP TRIGGER /*!50032 IF EXISTS */ `UpdatePlayersList`$$

CREATE
    /*!50017 DEFINER = 'admin'@'%' */
    TRIGGER `UpdatePlayersList` BEFORE INSERT ON `aos_matchs` 
    FOR EACH ROW BEGIN  
INSERT IGNORE INTO `aos_playerslist` (`name`,`ace_factor`) VALUES (new.initplayer,1);
END;
$$

DELIMITER ;
接下来,我想在aos_PlayerList表中更新ace_因子,每当一个新的匹配被插入到aos_matchs表中时,我会尝试使用一个触发器,该触发器将通过以下查询结果进行更新-

SELECT t1.initPlayer,t1.percentage/t2.full_percentage AS 'kill_percent'
            FROM (
                SELECT aos_matchs.MatchID,aos_matchs.`initPlayer`,SUM(CASE aos_matchs.Weapon
                WHEN 'GUNS' THEN aos_matchs.hitcount
                ELSE 70
                END) AS 'percentage',dtable.dead
                FROM aos_matchs
                LEFT JOIN (
                    SELECT MatchID,initPlayer AS dead
                    FROM aos_matchs
                    WHERE `event`='dead') dTable
                ON dTable.MatchID=aos_matchs.`MatchID` AND dTable.dead=aos_matchs.targPlayer
                WHERE aos_matchs.`Event`='hit' 
                AND dTable.dead IS NOT NULL
                GROUP BY aos_matchs.`MatchID`,aos_matchs.`initPlayer`,dtable.dead) t1
            LEFT JOIN (
                SELECT aos_matchs.MatchID,SUM(CASE aos_matchs.Weapon
                WHEN 'GUNS' THEN aos_matchs.hitcount
                ELSE 70
                END) AS 'full_percentage',dtable.dead
                FROM aos_matchs
                LEFT JOIN (
                    SELECT MatchID,initPlayer AS dead
                    FROM aos_matchs
                    WHERE `event`='dead') dTable
                ON dTable.MatchID=aos_matchs.`MatchID` AND dTable.dead=aos_matchs.targPlayer
                WHERE aos_matchs.`Event`='hit' 
                AND dTable.dead IS NOT NULL
                GROUP BY aos_matchs.`MatchID`,dtable.dead) t2
            ON t1.MatchID=t2.MatchID 
            AND t1.dead=t2.dead
            WHERE t1.MatchID = <matchID>
            AND t1.dead = <the tested dead player>
我希望这足够清楚,我只是在寻找一个触发器,它将获取每个死亡玩家的查询结果,并允许根据上述规则正确更新ace_factor列

这是我一直在尝试的触发器,但它不起作用,因为我可能做错了什么,因为我对触发器都是新手:

DELIMITER $$

USE `mytable`$$

CREATE
    TRIGGER `UpdateAceFactor` AFTER INSERT ON `aos_players`
    FOR EACH ROW BEGIN
    CREATE TEMPORARY TABLE mPlayers (pName VARCHAR(255));
    SET @cid =0;
    SET @mID = new.MatchID;

    INSERT INTO mPlayers
    SELECT initPlayer
    FROM aos_matchs
    WHERE MatchID = @mID
    AND `event`='dead';

    WHILE (SELECT COUNT(*) FROM mPlayers WHERE processed = 0)>0 DO
        SELECT Top 1 @cid = id FROM mPlayers WHERE processed = 0;
            DECLARE initP VARCHAR(255);
            DECLARE initPace INT;
            DECLARE cur1 CURSOR FOR (
            SELECT t1.initPlayer,t1.percentage/t2.full_percentage AS 'kill_percent'
            FROM (
                SELECT aos_matchs.MatchID,aos_matchs.`initPlayer`,SUM(CASE aos_matchs.Weapon
                WHEN 'GUNS' THEN aos_matchs.hitcount
                ELSE 70
                END) AS 'percentage',dtable.dead
                FROM aos_matchs
                LEFT JOIN (
                    SELECT MatchID,initPlayer AS dead
                    FROM aos_matchs
                    WHERE `event`='dead') dTable
                ON dTable.MatchID=aos_matchs.`MatchID` AND dTable.dead=aos_matchs.targPlayer
                WHERE aos_matchs.`Event`='hit' 
                AND dTable.dead IS NOT NULL
                GROUP BY aos_matchs.`MatchID`,aos_matchs.`initPlayer`,dtable.dead) t1
            LEFT JOIN (
                SELECT aos_matchs.MatchID,SUM(CASE aos_matchs.Weapon
                WHEN 'GUNS' THEN aos_matchs.hitcount
                ELSE 70
                END) AS 'full_percentage',dtable.dead
                FROM aos_matchs
                LEFT JOIN (
                    SELECT MatchID,initPlayer AS dead
                    FROM aos_matchs
                    WHERE `event`='dead') dTable
                ON dTable.MatchID=aos_matchs.`MatchID` AND dTable.dead=aos_matchs.targPlayer
                WHERE aos_matchs.`Event`='hit' 
                AND dTable.dead IS NOT NULL
                GROUP BY aos_matchs.`MatchID`,dtable.dead) t2
            ON t1.MatchID=t2.MatchID 
            AND t1.dead=t2.dead
            WHERE t1.MatchID = @mID
            AND t1.dead = @cid) kTable;

            DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

            OPEN cur1;

            the_loop: LOOP

                FETCH cur1 INTO initP,initPace;
                IF done THEN
                    LEAVE the_loop;
                END IF;

                IF initPace == (SELECT ace_factor FROM `aos_playerslist` WHERE `Name`=@cid) THEN
                    UPDATE `aos_playerslist`
                    SET ace_factor = (initPace+(initPace/initPace+(SELECT ace_factor FROM `aos_playerslist` WHERE `Name`=@cid)));
                    WHERE `name`=initP;

                    IF (SELECT ace_factor FROM `aos_playerslist` WHERE `Name`=@cid) > 1 THEN
                        UPDATE `aos_playerslist`
                        SET ace_factor = ((SELECT ace_factor FROM `aos_playerslist` WHERE `Name`=@cid)-(initPace/initPace+(SELECT ace_factor FROM `aos_playerslist` WHERE `Name`=@cid)));
                        WHERE `name`=@cid;
                    END IF;
                END IF;

                IF initPace > (SELECT ace_factor FROM `aos_playerslist` WHERE `Name`=@cid) THEN
                    UPDATE `aos_playerslist`
                    SET ace_factor = (initPace+(initPace/initPace+(SELECT ace_factor FROM `aos_playerslist` WHERE `Name`=@cid)));
                    WHERE `name`=initP;

                    IF (SELECT ace_factor FROM `aos_playerslist` WHERE `Name`=@cid) > 1 THEN
                        UPDATE `aos_playerslist`
                        SET ace_factor = ((SELECT ace_factor FROM `aos_playerslist` WHERE `Name`=@cid)-(initPace/initPace+(SELECT ace_factor FROM `aos_playerslist` WHERE `Name`=@cid)));
                        WHERE `name`=@cid;
                    END IF;
                END IF;

                IF initPace < (SELECT ace_factor FROM `aos_playerslist` WHERE `Name`=@cid) THEN
                    UPDATE `aos_playerslist`
                    SET ace_factor = (initPace+((SELECT ace_factor FROM `aos_playerslist` WHERE `Name`=@cid)/(initPace+(SELECT ace_factor FROM `aos_playerslist` WHERE `Name`=@cid))));
                    WHERE `name`=initP;

                    UPDATE `aos_playerslist`
                    SET ace_factor = ((SELECT ace_factor FROM `aos_playerslist` WHERE `Name`=@cid)-((initPace-(SELECT ace_factor FROM `aos_playerslist` WHERE `Name`=@cid))/initPace+(SELECT ace_factor FROM `aos_playerslist` WHERE `Name`=@cid)));
                    WHERE `name`=@cid;
                END IF;

            END LOOP the_loop;
            CLOSE cur1;

        UPDATE mPlayers SET processed = 1 WHERE id = @cid
        END;
    END;
    END$$

DELIMITER ;

只需像手工操作一样编写UPDATE语句。一旦你让它工作起来,把它放到CREATE TRIGGER语句中。如果你想要更具体的帮助,您需要更具体地说明要更新的内容。从您的示例中看,玩家表中的值是如何从Match和MatchInfo表中的数据生成的并不明显。玩家表中的值是通过在任何MatchInfo表中查找玩家名称并将其添加到玩家表中的不同触发器生成的如果还没有,它还会向“因子”列添加1个值。我需要在players表的factor列中执行的操作是使用一个特定的查询,该查询首先从players表中检查对手玩家的值。您需要在问题中解释如何使用此触发器。
DELIMITER $$

USE `mytable`$$

DROP TRIGGER /*!50032 IF EXISTS */ `UpdatePlayersList`$$

CREATE
    /*!50017 DEFINER = 'admin'@'%' */
    TRIGGER `UpdatePlayersList` BEFORE INSERT ON `aos_matchs` 
    FOR EACH ROW BEGIN  
INSERT IGNORE INTO `aos_playerslist` (`name`,`ace_factor`) VALUES (new.initplayer,1);
END;
$$

DELIMITER ;
SELECT t1.initPlayer,t1.percentage/t2.full_percentage AS 'kill_percent'
            FROM (
                SELECT aos_matchs.MatchID,aos_matchs.`initPlayer`,SUM(CASE aos_matchs.Weapon
                WHEN 'GUNS' THEN aos_matchs.hitcount
                ELSE 70
                END) AS 'percentage',dtable.dead
                FROM aos_matchs
                LEFT JOIN (
                    SELECT MatchID,initPlayer AS dead
                    FROM aos_matchs
                    WHERE `event`='dead') dTable
                ON dTable.MatchID=aos_matchs.`MatchID` AND dTable.dead=aos_matchs.targPlayer
                WHERE aos_matchs.`Event`='hit' 
                AND dTable.dead IS NOT NULL
                GROUP BY aos_matchs.`MatchID`,aos_matchs.`initPlayer`,dtable.dead) t1
            LEFT JOIN (
                SELECT aos_matchs.MatchID,SUM(CASE aos_matchs.Weapon
                WHEN 'GUNS' THEN aos_matchs.hitcount
                ELSE 70
                END) AS 'full_percentage',dtable.dead
                FROM aos_matchs
                LEFT JOIN (
                    SELECT MatchID,initPlayer AS dead
                    FROM aos_matchs
                    WHERE `event`='dead') dTable
                ON dTable.MatchID=aos_matchs.`MatchID` AND dTable.dead=aos_matchs.targPlayer
                WHERE aos_matchs.`Event`='hit' 
                AND dTable.dead IS NOT NULL
                GROUP BY aos_matchs.`MatchID`,dtable.dead) t2
            ON t1.MatchID=t2.MatchID 
            AND t1.dead=t2.dead
            WHERE t1.MatchID = <matchID>
            AND t1.dead = <the tested dead player>
if ace_factor1==ace_factor2 then
{
    if player_1 wins
    {
        new_acefactor1=ace_factor1+(ace_factor1/(ace_factor1+ace_factor2));
        new_acefactor2=ace_factor2-(ace_factor1/(ace_factor1+ace_factor2));
    }
    else if player_2 wins
    {
        new_acefactor1=ace_factor1-(ace_factor1/(ace_factor1+ace_factor2));
        new_acefactor2=ace_factor2+(ace_factor1/(ace_factor1+ace_factor2));
    }
}

else if ace_factor1>ace_factor2 then
{
/*Case 2a: the stronger player (player 1) wins the weaker (player 2)
/* then the change in the ace factor of the two opponents is determined by the ace factor of 
/*the weaker player
    if player_1 wins then
    {
        new_acefactor1=ace_factor1+(ace_factor2/(ace_factor1+ace_factor2));
        /*if the ace factor of player 2 (loser) equals "1" then it remains "1" (no 
        /*reduction)
        if ace_factor2==1 then 
        new_acefactor2=ace_factor2;
        else 
        /* if ace factor of player 2 is greater than "1" then it is reduced
        new_acefactor2=ace_factor2-(ace_factor2/(ace_factor1+ace_factor2));
    }


    /* Case 2b: the weaker player (player 2) wins the stronger player (player 1)

    else 
    {
    /* in that case the new ace factor of the weaker player (winner) is determined 
    /*(increased) by the value of the ace factor of his (stronger) opponent (loser)
        new_acefactor2=ace_factor2+(ace_factor1/(ace_factor1+ace_factor2));

    /* in that case the new ace factor of the stronger player (loser) is determined 
    /*(reduced) by the DIFFERENCE between the two ace factors 
    new_acefactor1=ace_factor1-((ace_factor1-ace_factor2)/(ace_factor1+ace_factor2));
    }
DELIMITER $$

USE `mytable`$$

CREATE
    TRIGGER `UpdateAceFactor` AFTER INSERT ON `aos_players`
    FOR EACH ROW BEGIN
    CREATE TEMPORARY TABLE mPlayers (pName VARCHAR(255));
    SET @cid =0;
    SET @mID = new.MatchID;

    INSERT INTO mPlayers
    SELECT initPlayer
    FROM aos_matchs
    WHERE MatchID = @mID
    AND `event`='dead';

    WHILE (SELECT COUNT(*) FROM mPlayers WHERE processed = 0)>0 DO
        SELECT Top 1 @cid = id FROM mPlayers WHERE processed = 0;
            DECLARE initP VARCHAR(255);
            DECLARE initPace INT;
            DECLARE cur1 CURSOR FOR (
            SELECT t1.initPlayer,t1.percentage/t2.full_percentage AS 'kill_percent'
            FROM (
                SELECT aos_matchs.MatchID,aos_matchs.`initPlayer`,SUM(CASE aos_matchs.Weapon
                WHEN 'GUNS' THEN aos_matchs.hitcount
                ELSE 70
                END) AS 'percentage',dtable.dead
                FROM aos_matchs
                LEFT JOIN (
                    SELECT MatchID,initPlayer AS dead
                    FROM aos_matchs
                    WHERE `event`='dead') dTable
                ON dTable.MatchID=aos_matchs.`MatchID` AND dTable.dead=aos_matchs.targPlayer
                WHERE aos_matchs.`Event`='hit' 
                AND dTable.dead IS NOT NULL
                GROUP BY aos_matchs.`MatchID`,aos_matchs.`initPlayer`,dtable.dead) t1
            LEFT JOIN (
                SELECT aos_matchs.MatchID,SUM(CASE aos_matchs.Weapon
                WHEN 'GUNS' THEN aos_matchs.hitcount
                ELSE 70
                END) AS 'full_percentage',dtable.dead
                FROM aos_matchs
                LEFT JOIN (
                    SELECT MatchID,initPlayer AS dead
                    FROM aos_matchs
                    WHERE `event`='dead') dTable
                ON dTable.MatchID=aos_matchs.`MatchID` AND dTable.dead=aos_matchs.targPlayer
                WHERE aos_matchs.`Event`='hit' 
                AND dTable.dead IS NOT NULL
                GROUP BY aos_matchs.`MatchID`,dtable.dead) t2
            ON t1.MatchID=t2.MatchID 
            AND t1.dead=t2.dead
            WHERE t1.MatchID = @mID
            AND t1.dead = @cid) kTable;

            DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

            OPEN cur1;

            the_loop: LOOP

                FETCH cur1 INTO initP,initPace;
                IF done THEN
                    LEAVE the_loop;
                END IF;

                IF initPace == (SELECT ace_factor FROM `aos_playerslist` WHERE `Name`=@cid) THEN
                    UPDATE `aos_playerslist`
                    SET ace_factor = (initPace+(initPace/initPace+(SELECT ace_factor FROM `aos_playerslist` WHERE `Name`=@cid)));
                    WHERE `name`=initP;

                    IF (SELECT ace_factor FROM `aos_playerslist` WHERE `Name`=@cid) > 1 THEN
                        UPDATE `aos_playerslist`
                        SET ace_factor = ((SELECT ace_factor FROM `aos_playerslist` WHERE `Name`=@cid)-(initPace/initPace+(SELECT ace_factor FROM `aos_playerslist` WHERE `Name`=@cid)));
                        WHERE `name`=@cid;
                    END IF;
                END IF;

                IF initPace > (SELECT ace_factor FROM `aos_playerslist` WHERE `Name`=@cid) THEN
                    UPDATE `aos_playerslist`
                    SET ace_factor = (initPace+(initPace/initPace+(SELECT ace_factor FROM `aos_playerslist` WHERE `Name`=@cid)));
                    WHERE `name`=initP;

                    IF (SELECT ace_factor FROM `aos_playerslist` WHERE `Name`=@cid) > 1 THEN
                        UPDATE `aos_playerslist`
                        SET ace_factor = ((SELECT ace_factor FROM `aos_playerslist` WHERE `Name`=@cid)-(initPace/initPace+(SELECT ace_factor FROM `aos_playerslist` WHERE `Name`=@cid)));
                        WHERE `name`=@cid;
                    END IF;
                END IF;

                IF initPace < (SELECT ace_factor FROM `aos_playerslist` WHERE `Name`=@cid) THEN
                    UPDATE `aos_playerslist`
                    SET ace_factor = (initPace+((SELECT ace_factor FROM `aos_playerslist` WHERE `Name`=@cid)/(initPace+(SELECT ace_factor FROM `aos_playerslist` WHERE `Name`=@cid))));
                    WHERE `name`=initP;

                    UPDATE `aos_playerslist`
                    SET ace_factor = ((SELECT ace_factor FROM `aos_playerslist` WHERE `Name`=@cid)-((initPace-(SELECT ace_factor FROM `aos_playerslist` WHERE `Name`=@cid))/initPace+(SELECT ace_factor FROM `aos_playerslist` WHERE `Name`=@cid)));
                    WHERE `name`=@cid;
                END IF;

            END LOOP the_loop;
            CLOSE cur1;

        UPDATE mPlayers SET processed = 1 WHERE id = @cid
        END;
    END;
    END$$

DELIMITER ;