3

カーソル/ループ/php側なしでこれを行うためのより良い方法があるかどうか疑問に思っています。私は 5 年以上 DBA をしており、:= ステートメントに出くわしました。とてもかっこいい。

個人 ID と購入したチケット数を含むテーブル (tblPeople)。

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
4

2 に答える 2

3

Numbers1から人が購入できるチケットの最大数までのすべての数字を含むユーティリティ テーブルを追加します。次に、次のようなことができます。

INSERT INTO tblTickets (PersonId)
SELECT s.PersonId
FROM tblPeople s, Numbers n
WHERE n.number <= s.NumTickets
于 2013-01-08T07:01:35.423 に答える
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();

それが役に立てば幸い...

于 2013-01-08T07:46:55.787 に答える