MySQL:仅在满足特定条件时更新项目

时间:2016-06-02 00:22:57

标签: mysql sql relational-database

有人知道如果其中一个列不等于表中另一行中的同一列,那么如何更新行?

让我解释一下。考虑一下这个表。它存储了一些预订,管理员可以决定批准​​哪一个。

Booking |  Time | Approved
   0    |  5:00 |   NO
   1    |  5:00 |   NO
   2    |  6:00 |   YES
   3    |  6:00 |   NO

预订请求可能会重叠,例如预订0和1。管理员可以决定批准​​0或1。

但批准的预订不能重叠。例如,由于预订2已经批准为6:00,因此预订3无法获得批准。除非管理员决定先取消预订2。

如何为此编写查询以检查是否会发生冲突?我正在思考以下几点:

 UPDATE requests
 SET Approved = 'YES'
 WHERE Booking = 3
 AND NOT EXISTS (
    (SELECT Time 
    FROM requests
    WHERE Booking = 3)
    = 
    (SELECT Time
    From requests
    WHERE Booking != 3)
 );

但这不起作用。

非常感谢任何帮助。

作为旁注。我的实际问题有点复杂。该表看起来更像

Booking |  Start Time | End Time |Approved
   0    |  5:00       |   6:00   | NO
   1    |  5:00       |   7:00   | NO
   2    |  6:00       |   8:00   | YES
   3    |  6:00       |   9:00   | NO

我试图阻止重叠预订。但我确定如果我的问题的简单版本的语法正确,那么我也能够找出复杂的版本。

3 个答案:

答案 0 :(得分:3)

您未正确使用NOT EXISTS。它的参数应该是单个子查询,而不是比较两个子查询的表达式。在您的情况下,子查询中的条件是它是同一时间,但ID与您正在更新的ID不同,而另一个已经被批准。

UPDATE request AS r1
SET approved = 'YES'
WHERE r1.id = 3
AND NOT EXISTS (
    SELECT *
    FROM request AS r2
    WHERE r2.time = r1.time AND r2.id != r1.id AND r2.approved = 'YES'
)

要解决此错误,请使用LEFT JOIN / NULL模式。

UPDATE request AS r1
LEFT JOIN request AS r2 ON r2.time = r1.time AND r2.id != r1.id AND r2.approved = 'YES'
SET r1.approved = 'YES'
WHERE r1.id = 3 AND r2.id IS NULL

答案 1 :(得分:2)

您错误地使用了exists。但是在mysql中,您无法在from子句中指定要更新的表,因此无论如何都无法使用它。

但你可以使用join。因此,对于您的简单版本:

update requests r1
left join requests r2
on r1.id <> r2.id and r1.time = r2.time and r2.Approved = 'YES'
set r1.Approved = 'YES'
where r1.id = 3 
and r2.id is null;

您当然也可以使用联接来处理更复杂的版本。既然你想自己尝试一下,我会在明天添加解决方案(或者如果你要求的话)。

或者你可以先做一个选择。在那里你可以使用exists。然后,您将能够向用户显示错误消息。如果已经存在条目,则此更新将无效。

select count(*) 
from requests r1
where r1.id = 3
and not exists 
  (select * from requests r2
   where r1.id <> r2.id and r1.time = r2.time and r2.Approved = 'YES'
  );

答案 2 :(得分:0)

尝试这样的事情。我从ID中选择要批准的时间,然后检查表中是否已经存在批准的时间='YES' 如果不存在,请更新。

update request
set
approved = 'YES'
where not exists(select 'yes' from request where time = 
(select time from request where id=1) and approved='YES')