【问题标题】:How delete records from table A and B, if B does not contain specific value如果 B 不包含特定值,如何从表 A 和 B 中删除记录
【发布时间】:2020-07-23 16:27:35
【问题描述】:

我正在尝试编写 SQL 查询以从两个表中删除数据 - AB。它们用一个键连接,我只需要检查B 是否在一列中有特定值reservation

长话短说,我有roomsbeds 的桌子,我需要检查room 是否有任何预订。如果没有,我需要删除room 本身及其所有beds

我尝试了两个查询,但都没有给我预期的结果。表B 比较大,所以我试图在一个查询中使其尽可能快。

-- gives me always 0 records
DELETE
  a, b
FROM
  rooms a, beds b
WHERE
  a.id = b.id_room AND
NOT EXISTS
  (SELECT 1 FROM beds WHERE id_room = '45' AND state != 'reservation')


-- deletes all records, but rows where state = 'reservation'
DELETE
  a, b
FROM 
  rooms a, beds b
WHERE
  a.id = b.id_room AND id_room = '45' AND state != 'reservation'

示例数据集:

-- rooms
-------------
| id | Name |
-------------
| 1  | 601  |
| 2  | 602  |
| 3  | 603  |

-- beds
-----------------------------|
| id | id_room | state       |
-----------------------------|
| 1  | 1       | free        |
| 2  | 1       | free        |
| 3  | 1       | reservation |
| 4  | 2       | free        |
| 5  | 2       | free        |
| 6  | 3       | reservation |

预期结果:

房间13 在表bedsstate 列中具有值reservation,因此无法删除。房间 2 没有预订,因此可以删除它,并且应该删除它包括所有床位 - 所以查询应该从表 rooms 中删除记录 2,并从表 @987654343 中删除记录 45 @。

我总是想只删除一个房间(包括床),所以我需要包含关于房间ID 的条件来计算。

【问题讨论】:

  • 样本数据和期望的结果将阐明您想要做什么。
  • 更新您的问题,添加适当的数据样本和预期结果为表格文本
  • @scaisEdge ,Gordon Linoff - 我添加了示例数据集并描述了预期结果,我希望它有助于澄清我的问题。

标签: mysql sql


【解决方案1】:

这个查询:

select id_room
from (
  select id_room, state from beds
  union
  select ?, ''
) t 
where id_room = ?
group by id_room
having sum(state = 'reservation') = 0

返回应该删除的房间的id,因为它的任何床都没有'reservation',或者它没有床。
? 都替换为您搜索的房间的 ID。

将其加入DELETE 语句中的表:

delete r, b
from rooms r 
inner join (
  select id_room
  from (
    select id_room, state from beds
    union
    select ?, ''
  ) t 
  where id_room = ?
  group by id_room
  having sum(state = 'reservation') = 0
) t on t.id_room = r.id
left join beds b
on b.id_room = t.id_room

请参阅demo

【讨论】:

  • 完美,我添加了条件WHERE id_room = {ID_ROOM},这正是我所需要的。非常感谢,你拯救了我的一天。
  • 现在,我发现了一个小问题。如果beds表中没有记录,那么如果房间还没有床,这个查询不会删除它。在这种情况下,这里有机会编辑删除房间的条件吗?
【解决方案2】:

您可以尝试在表之间使用左连接并检查不匹配的值

    DELETE  beds, rooms
    FROM  rooms a
    LEFT  JOIN beds b ON a.id = b.id_room 
        AND b.state = 'reservation'
    WHERE b.id_room is null

并基于您的代码示例

SELECT a.id, b.id 
FROM  rooms a 
LEFT  JOIN beds b ON a.id = b.id_room 
AND b.state = 'reservation' and 
    b.id_room = 45 WHERE b.id_room is null

    DELETE romms, beds
    FROM  rooms a
    LEFT  JOIN beds b ON a.id = b.id_room 
        AND b.state = 'reservation'
    WHERE b.id_room is null
    AND  a.id = 45 

【讨论】:

  • 它似乎有效,但查询仅从表 A 中删除记录,表 B 未触及。我还添加了关于房间ID的条件,但不影响结果。
  • 使用语法delete ....从delete和from之间的表中删除应该是delete ..所以无论如何都要更好地检查..使用expiiclit表名id_room进行轻微更改.. ..最终尝试发布代码你真的在使用..
  • 如果我将DELETE 更改为SELECT 以查看选择了哪些记录,我会得到所有房间的列表(在a.id 中)并且在b.id 中总共是NULL记录。我正在尝试您的查询,只是我添加了关于id_room 的条件,因为我总是只需要检查具有特定 ID 的房间,而不是所有房间。 SELECT a.id, b.id FROM rooms a LEFT JOIN beds b ON a.id = b.id_room AND b.state = 'reservation' and b.id_room = 45 WHERE b.id_room is null
  • 此查询成功删除了room,但没有删除beds。我不确定,我做错了什么。
  • 你确定你在某处没有存储过程吗??你确定连接子句是正确的并且与用于测试的数据一致吗.. 无论如何回答更新了.. 更改了表名的顺序..
【解决方案3】:

我想你想要:

DELETE r, b
    FROM rooms r JOIN
         beds b
         ON a.id = b.id_room LEFT JOIN
         (SELECT b2.id_room
          FROM beds b2
          WHERE b2.state = 'reservation'
         ) b2
         ON b2.id_room = b.id_room
    WHERE b2.id_room IS NULL;

【讨论】:

  • 它给了我这个错误Can't specify target table for update in FROM clause
  • @sylar32 。 . .呸!我修复了使用LEFT JOIN 的答案。
  • 现在可以了,但是这个查询会删除所有房间和所有床位,无论是否包含reservation。我在子查询中添加了条件AND b2.id_room = 45,因为我总是只需要检查一个房间,而不是所有房间。我不确定,如果我正确解释了我需要删除的内容。我在上面添加了示例数据集和预期结果以澄清我的问题。
  • @Sylar32 。 . .我没有意识到“45”是针对这个问题的。我想你真的想删除所有符合条件的房间。您可以将该条件添加到外部查询中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-25
  • 2020-02-23
相关资源
最近更新 更多