仅在值为空时如何更新,否则在下一行更新

时间:2019-04-23 19:56:00

标签: php mysql

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

+---------+---------+-------------+-------------+-------------+
|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语法有错误;在第1行的'IF(person1 IS NULL,person1,IF(person2 IS NULL,person2,IF(person3 IS NULL,back,back')''附近检查与您的MariaDB服务器版本相对应的手册以使用正确的语法

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

4 个答案:

答案 0 :(得分:1)

所以我找到了解决方案。...

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

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

答案 1 :(得分:0)

请参见下面的示例代码。 我所做的更新任务表的方法是使表内部与其自身相连,以获取旧值。

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

确保您要更新的表具有唯一的ID,可以通过它们进行联接,因此只有一条记录与其自身联接。

剩下的就是用case语句更新person列。 如果人员列为空,并且您尚未更新任何先前的人员列,则可以继续进行更新。

我包括了我尝试模拟到您的测试架构以及更新查询。

我在这里进行测试: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';

答案 2 :(得分:0)

长期来说,最好的选择是重新设计桌子:

toggle()

或更佳

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

在上述两种方法中,您只需删除要“未分配”人员的行,而只需插入行即可对其进行分配。如果订单确实很重要,它可能会使最复杂的部分变得最复杂,但幅度不会太大。

答案 3 :(得分:0)

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

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,并且这些结果将在IF()条件下用于下一个SET。因此,如果将person2设置为一个值,然后检查person3,将看到person2已被填充,并设置person3,则对person4的检查将看到person3具有值,并且也将person4设置为。反向检查可以完全避免这种情况。