在循环内循环以更新db记录

时间:2013-01-16 04:35:32

标签: php mysql loops

我有一个包含以下数据的交易表:

dealID   |   date    |   followUP  |  user
1        |2012-10-15 |    Yes      |
2        |2012-12-24 |    Yes      |
3        |2013-01-05 |             |
4        |2013-02-02 |    Yes      |
5        |2013-02-02 |    Yes      |

用户表和我的用户列表

userID    | name
1         | john
2         | eric
3         | anne

我想要做的是查询第一个将followUP设置为'YES'的表,然后从结果中将用户从用户表中依次分配给它们,这样我的最终交易表将如下所示

dealID   |   date    |   followUP  | userID
1        |2012-10-15 |    Yes      | 1
2        |2012-12-24 |    Yes      | 2
3        |2013-01-05 |             |
4        |2013-02-02 |    Yes      | 3
5        |2013-02-02 |    Yes      | 1

我知道它是一个循环,但由于某种原因,我无法弄清楚如何设置第二个循环来分配用户的值。任何帮助将不胜感激。

4 个答案:

答案 0 :(得分:2)

首先将您的用户ID放入数组中,使其显示为:

$uids = array(1, 2, 3);

然后,当从交易表中读取记录时,编写更新查询,如下所示:

$follow_up_user_idx = 0;
$update_queries = array();
while($row=mysqli_fetch_assoc($result)) {
    // ... do whatever you need to
    if($row['followUP'] != 'Yes') continue;
    $update_queries[] = "UPDATE `deals` SET `user` = '" . $uids[$follow_up_user_idx] . "'
                         WHERE `dealID` = '" . $row['dealID'] . "' LIMIT 1";
    $follow_up_user_idx++;
    if($follow_up_user_idx > count($uids) - 1) $follow_up_user_idx = 0;
}

现在您拥有所有更新查询。只需执行它们:

foreach($update_queries as $uq) {
    mysqli_query($link, $uq);
}

答案 1 :(得分:1)

你必须按照一系列步骤来实现你所提到的。

1)从followUP为“是”的数据库中获取所有记录 可以说第一个表是deals。因此,请获取followUP为“是”的所有记录 可以说,你的结果是$ deals_details。

2)从数据库中获取所有用户(名称) 可以说第二个表是users。因此,获取所有用户。
假设您在$ users_details数组中拥有所有用户的名字 在单独的变量中获取系统中的总用户数,例如$ users_count。

3)遍历$ deals_details并从$ users_details开始按顺序分配每个用户。

$i = 0;
foreach($deals_details as $keyDD => $valueDD){
    $user = $users_details[$i];
    $i++;
    if($i == $users_count)
        $i = 0;
    $query = "update `deals` set user = '".$user."' where dealID = '".$valueDD['dealID']."'";

    //fire query
    //$link is connection variable.
    mysqli_query($link, $query);
}

答案 2 :(得分:1)

表用户 + --------------- + --------------- + ------------ + | user_id |用户名| user_level | + --------------- + --------------- + ------------ + | 1 | superadmin |管理员| | 2 | subadmin |管理员| | 3 | team1 |团队| | 4 | team2 |团队| | 5 | team3 |团队| | 6 | customer1 |客户| | 7 | customer2 |客户| | 8 | customer3 |客户| | 9 | customer4 |客户| + --------------- + --------------- + ------------ + 表投诉: + --------------- + --------------- + ------------ + | complaint_id |投诉| user_id | + --------------- + --------------- + ------------ + | 1 | os问题| 7 | | 2 | USB问题| 8 | | 3 | OS上市| 7 | | 4 |高清问题| 9 | | 5 | DVD问题| 6 | | 6 | SW问题| 9 | | 7 |网络问题| 9 | | 8 |系统问题| 6 | + --------------- + --------------- + ------------ + 表assign_work + --------------- + ------------ + | complaint_id | user_id | + --------------- + ------------ + | 1 | 3 | | 2 | 4 | | 3 | 5 | | 4 | 3 | | 5 | 4 | | 6 | 5 | | 7 | 3 | | 8 | 4 | + --------------- + ------------ +

当客户提出投诉数据时,还应保存在投诉表中 complaint_id应同时保存在assign_work表中  user_id也按顺序保存,从用户表中获取只是人员id的团队。 我是新的ph请任何人帮助我。

答案 3 :(得分:0)

这可能是一个糟糕的设计决定。在不了解您的应用程序的情况下,我很想等待用户变得可用/请求交易,然后分配给他们(从队列中)下一个需要跟进的交易。即使您有充分的理由在用户“可用”之前分配用户,您也可以考虑在基于某些适当的业务逻辑进行交易创建/修改时这样做(例如,维护用户队列以分配给下一笔交易)。

实际上,使用简单的UPDATE语句执行此操作没有特别好的方法。纯粹在数据库中完成它的一种方法是使用存储过程(但它并不特别是并发安全,因为在关闭和重新打开Users游标之间对_curUser表的更改可能会导致不良影响;出于此过程的目的,可以将Users复制到临时表中,具体取决于您所需的逻辑):

DELIMITER //

CREATE PROCEDURE assignDeals() BEGIN
  DECLARE _userID, _dealID BIGINT UNSIGNED;
  DECLARE _done BOOLEAN DEFAULT FALSE;

  DECLARE _curUser CURSOR FOR
    SELECT   userID
    FROM     users
    ORDER BY userID;

  DECLARE _curDeal CURSOR FOR
    SELECT   dealID
    FROM     deals
    WHERE    followUP = 'Yes'
    ORDER BY dealID
    FOR UPDATE;

  DECLARE CONTINUE HANDLER FOR NOT FOUND
    SET _done := TRUE;

  PREPARE stmt FROM 'UPDATE deals SET userID = ? WHERE dealID = ?';

  OPEN _curUser;
  OPEN _curDeal;

  readDeal: LOOP
    FETCH _curDeal INTO _dealID;
    IF _done THEN
      LEAVE readDeal;
    END IF;

    FETCH _curUser INTO _userID;
    IF _done THEN
      SET _done := FALSE;
      CLOSE _curUser;
      OPEN  _curUser;
      FETCH _curUser INTO _userID;
      IF _done THEN
        SIGNAL SQLSTATE VALUE '45000' SET
          MESSAGE_TEXT = 'No users';
        LEAVE readDeal;
      END IF;
    END IF;

    SET @userID := _userID, @dealID := _dealID;
    EXECUTE stmt USING @userID, @dealID;
  END LOOP readDeal;

  CLOSE _curUser;
  CLOSE _curDeal;

  DEALLOCATE PREPARE stmt;
END//

DELIMITER ;

sqlfiddle上查看。