MySQL - 根据列值插入多行

时间:2013-01-08 05:24:58

标签: mysql loops cursor

我有查询工作,只是想知道是否有更好的方法来做这个没有游标/循环/ PHP方面。我是一名DBA已经5年多了,只是遇到了:=声明。很酷。

表(tblPeople),其中包含人员ID和他们购买的门票数量。

PersonId  NumTickets
1         3  
2         1 
3         1

然后,我想根据他们购买的门票数量,为每个人分配一张新桌子(tblTickets)。 TicketId是一个关键的自动增量列。

TicketId  PersonId
100       1
101       1
102       1 
103       2
104       3 

这是代码。它遍历整个tblPeople,一遍又一遍地增加一个名为rowID的新计算列。然后我根据他们在WHERE子句中购买的票数过滤出行。我看到的问题是子查询是巨大的,我拥有的人越多,子查询就越大。只是不确定是否有更好的方法来写这个。

INSERT INTO tblTickets (PersonId)
    SELECT PersonId
    FROM (
        SELECT s.PersonId, s.NumTickets,
            @rowID := IF(@lastPersonId = s.PersonId and @lastNumTickets = s.NumTickets, @rowID + 1, 0) AS rowID,
            @lastPersonId := s.PersonId,
            @lastNumTickets := s.NumTickets
        FROM tblPeople m,
            (SELECT @rowID := 0, @lastPersonId := 0, @lastNumTickets := 0) t
            INNER JOIN tblPeople s 
        ) tbl
    WHERE rowID < NumTickets

2 个答案:

答案 0 :(得分:3)

我会添加一个实用程序表Numbers,其中包含从1到最大票数可以购买的所有数字。然后你可以做这样的事情:

INSERT INTO tblTickets (PersonId)
SELECT s.PersonId
FROM tblPeople s, Numbers n
WHERE n.number <= s.NumTickets

答案 1 :(得分:1)

以下存储过程将满足您的目的......

DELIMITER $$

USE <your database name> $$

DROP PROCEDURE IF EXISTS `update_ticket_value2`$$

CREATE PROCEDURE `update_ticket_value2`()
BEGIN
DECLARE index_value INT;
DECLARE loop_variable INT;  


SET @KeyValue = 100;
SET @LastPersonID = 0;
SET @TicketNum = 0;

SET @PersonIDToHandle = 0;

SELECT @PersonIDToHandle = PersonID, @TicketNum = NumTickets
FROM tblPeople
WHERE PersonId > @LastPersonID
ORDER BY PersonId
LIMIT 0,1;

WHILE @PersonIDToHandle IS NOT NULL
DO
    SET loop_variable = 0;

    WHILE(loop_variable < @TicketNum) DO
        INSERT INTO tblTickets(TicketId, PersonId) VALUES(@KeyValue + loop_variable, @PersonIDToHandle);
        SET loop_variable = loop_variable + 1;
    END WHILE;  

    SET @LastPersonID = @PersonIDToHandle;
    SET @PersonIDToHandle = NULL;
    SET @KeyValue = @KeyValue + @TicketNum;

    SELECT @PersonIDToHandle := PersonID, @TicketNum := NumTickets
    FROM tblPeople
    WHERE PersonId > @LastPersonID
    ORDER BY PersonId
    LIMIT 0,1;
END WHILE;

    END$$

DELIMITER ;

将程序称为:

CALL update_ticket_value2();

希望它有所帮助...