0

我有一个任务分配系统,我想将人员分配给某些任务。该表的布局如下:

+---------+---------+-------------+-------------+-------------+
|Task name| person1 | person2     | person3     | person4     |
+---------+---------+-------------+-------------+-------------+

如果一个任务已经分配给例如 2 个人,我希望更新功能填充第 3 个人。所以它基本上检查值是否为空,如果是则输入数据,否则检查下一列中的值是否为空并将其放置在那里,并为所有列继续此操作。

我已经尝试过了,但这会输出错误:

UPDATE data SET IF(person1 IS NULL, person1, 
                  IF(person2 IS NULL,person2,
                    IF(person3 IS NULL, person3,
                      IF(person4 IS NULL, person4,
                        IF(person5 IS NULL, person5, person6)))))
                 ='$person_name' WHERE id=$id

这会输出以下错误:

您的 SQL 语法有错误;检查与您的 MariaDB 服务器版本相对应的手册,以在第 1 行的 'IF(person1 IS NULL, person1, IF(person2 IS NULL, person2, IF(person3 IS NULL, back' 附近使用正确的语法

但据我所知,这是一个普遍错误。

4

4 回答 4

1

请参阅下面的示例代码。我为更新任务表所做的是将表内部加入它本身以获得旧值。

我们需要将表与自身连接的原因是因为一个表将保存具有更新值的列,而另一个不会更改其值。这样我们就可以检查列是否已更新。

确保您正在更新的表有一个唯一的 id 来加入它们,因此只有一条记录与其自身相连。

剩下的就是用 case 语句更新 people 列。如果人员列是空的并且您没有更新任何以前的人员列,那么您可以继续更新它。

我已经包含了我试图模拟给你的测试模式,以及更新查询。

这是我测试它的地方:https ://www.db-fiddle.com/f/bxSWZhj7NXfm7J5pCQ5Kw1/0

create table my_tasks(
task_name VARCHAR(100),
 person1 VARCHAR(100),
  person2 VARCHAR(100),
  person3 VARCHAR(100),
  person4 VARCHAR(100)

);

insert into my_tasks (task_name,person1,person2,person3,person4) values('test',NULL,'fsd','fsd','fsdfs'),('test2','fsdfs',NULL,NULL,NULL),('test3','ffdsfs',NULL,'fsdfsf',NULL);

UPDATE my_tasks INNER JOIN my_tasks as tasks2 on my_tasks.task_name=tasks2.task_name
  SET my_tasks.person1= CASE 
    WHEN my_tasks.person1 IS NULL THEN 'person 1 update'
    ELSE my_tasks.person1
  END,
  my_tasks.person2 = CASE 
    WHEN  my_tasks.person2 IS NULL AND my_tasks.person1=tasks2.person1
    THEN 'person 2 update'
    ELSE my_tasks.person2
   END,
   my_tasks.person3 = CASE
        WHEN my_tasks.person3 IS NULL AND my_tasks.person2=tasks2.person2 AND my_tasks.person1=tasks2.person1
        THEN 'person 3 update'
        ELSE my_tasks.person3
   END,
   my_tasks.person4 = CASE
    WHEN my_tasks.person4 IS NULL AND my_tasks.person3=tasks2.person3 AND my_tasks.person2=tasks2.person2 AND my_tasks.person1=tasks2.person1
    THEN 'person 4 update'
    ELSE my_tasks.person4
   END

WHERE my_tasks.task_name='test3';
于 2019-04-23T21:02:15.767 回答
1

这应该可以满足您的需要:

UPDATE `data`
   SET person4 = IF(person4 IS NULL AND person3 IS NOT NULL, 'value', person4),
       person3 = IF(person3 IS NULL AND person2 IS NOT NULL, 'value', person3),
       person2 = IF(person2 IS NULL AND person1 IS NOT NULL, 'value', person2),
       person1 = IF(person1 IS NULL, 'value', person1)
 WHERE id = $id;

编辑:您想以相反的顺序执行 SET 的原因是 MySQL 将单独执行每个 SET,并且这些结果将用于下一个 SET 的 IF() 条件。因此,如果您将 person2 设置为一个值,然后检查 person3,它将看到 person2 已被填写并 SET person3,然后对 person4 的检查将看到 person3 有一个值并设置 person4。以相反的顺序检查可以完全避免这种情况。

于 2019-04-24T16:03:28.330 回答
1

所以我找到了一个解决方案......

我已经通过 select 语句提取了所有表数据。然后为每一列做了很多 php if 语句。

如果单元格为空,则更新该单元格,否则检查下一列中的单元格是否为空。

于 2019-09-09T17:36:17.867 回答
0

从长远来看,您最好的选择是重新设计表格:

Tasks: TaskId (PK, auto inc), TaskName (varchar)
Task_Assignees: TaskId (references Tasks.TaskId), Person (varchar)

或更好

Tasks: TaskId (PK, auto inc), TaskName (varchar)
Workers: WorkerId (PK, auto inc), WorkerName (varchar)
Task_Workers: TaskId (references Tasks.TaskId), WorkerId (references Workers.WorkerId)

在上述任一情况下,您只需删除行以“取消分配”人员,然后插入行以分配他们。如果订单真的很重要,它可能会变得稍微复杂一点,但不会复杂很多。

于 2019-04-23T22:59:31.360 回答