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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在值为空时更新,否则在下一行更新相关的知识,希望对你有一定的参考价值。

我有一个任务分配系统,我想分配人员完成某些任务。表格如下:

+---------+---------+-------------+-------------+-------------+
|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服务器版本对应的手册,以便在'IF(person1 IS NULL,person1,IF(person2 IS NULL,person2,IF(person3 IS NULL,返回')第1行附近使用正确的语法

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

答案

请参阅下面的示例代码我更新任务表所做的是将表内部连接到自身以获取旧值。

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

确保您要更新的表具有唯一的ID以加入它们,因此只有一个记录与其自身连接。

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

我已经将我尝试模拟的测试模式以及更新查询包括在内。

这是我测试它的地方: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';
另一答案

长期的最佳选择是重新设计表格:

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)

在上面的任何一个中,您只需删除行以“取消分配”人员,只需插入行来分配它们。如果订单真的很重要,它可能会变得更复杂,但不是很多。

另一答案

这应该适合您的需要:

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已经填写并且设置了person3,那么对person4的检查将看到person3有一个值并且也设置了person4。以相反顺序检查可以完全避免这种情况。

以上是关于如何在值为空时更新,否则在下一行更新的主要内容,如果未能解决你的问题,请参考以下文章

我有一种形式可以更新mysql中的某些值,当输入为空时,如何避免更新单元格?

mysql 在值为null的字段插入数据!

为啥 TargetNullValue 更新可为空的 Source

数据绑定值为空时如何在 DataGridViewComboBoxColumn 中显示文本

SQl 在字段为空时更新列

仅当字段为空时才更新来自 select 语句的查询