SQL:根据另一个表的计数结果更新一个表中的列

Posted

技术标签:

【中文标题】SQL:根据另一个表的计数结果更新一个表中的列【英文标题】:SQL: updating a column in one table based on a count result from another table 【发布时间】:2019-10-20 03:56:49 【问题描述】:

我有一个名为 GUEST 的表和一个名为 HOTEL_BOOKING 的表。

我想更新GUEST 表中名为guest_nobookings 的列(这是客人在酒店进行的预订数量)。

我可以从HOTEL_BOOKING 表中通过根据客人号码对酒店预订号码进行计数来获取客人的预订数量。

这是我目前所拥有的:

SELECT COUNT(hotel_bookingno) 
  FROM hotel_booking 
 GROUP BY guest_no;

这为我提供了每位入住该酒店的客人的预订数量。要更新 GUEST 表,我已经尝试过:

UPDATE guest 
   SET (guest_nobookings = (SELECT COUNT(hotel_bookingno) 
                              FROM hotel_booking 
                             GROUP BY guest_no));

但是,当我尝试此操作时,出现“单行子查询返回多行”错误。

有没有更直接的方法解决这个问题?

提前致谢!

【问题讨论】:

【参考方案1】:

您可以在此处使用相关子查询进行更新:

UPDATE guest g
SET guest_nobookings = (SELECT COUNT(*) FROM hotel_booking hb
                        WHERE hb.guest_no = g.hotel_bookingno);

您可能需要稍微更改以上内容才能使其正常工作。作为旁注,您可能需要重新考虑您的设计,甚至避免进行此更新。原因是每次hotel_booking 表中的状态更改时,计数聚合可能会变得无效,并且必须重新计算。一般来说,我们尽量避免在 SQL 中存储原始数据的聚合。

【讨论】:

GROUP BY 在子查询中是不必要且令人困惑的。【参考方案2】:

为什么要在两个表中拥有健全的数据?这将导致其中一个数据不一致。 (正如蒂姆已经描述的那样)

我的建议是使用view 获取guest 的所有详细信息,并在视图中使用hotel_bookings 表中的计数。

如果你真的想更新计数,那么你可以使用merge 语句如下:

Merge into guest g
Using (select COUNT(*) as cnt, hb.guest_no
FROM hotel_booking hb 
GROUP BY hb.guest_no) hb
On (hb.guest_no = g.hotel_bookingno)
When matched then 
Update set g.guest_nobookings = hb.cnt;

干杯!!

【讨论】:

【参考方案3】:
UPDATE guest  
SET guest_nobookings = (  
       WITH t1 AS (  
                    SELECT COUNT(*) no_bk, guest_no  FROM  hotel_booking  
                    GROUP BY hotel_booking.guest_no  
                  )  
       SELECT no_bk FROM t1  
       WHERE guest_no = guest.hotel_bookingno  
   );  

这是使用 WITH 子句更新表的另一种方法。

【讨论】:

以上是关于SQL:根据另一个表的计数结果更新一个表中的列的主要内容,如果未能解决你的问题,请参考以下文章

MySQL - 根据另一个表的列计数从一个表中获取记录

基于匹配值的雪花SQL计数和从另一个表求和

如何根据从另一个表中选择的结果更新一个表中的列

根据 SQL Server 2008R2 中表中的列获取计数

基于另一个表的计数的表中的红移样本

从另一个表中逐行计数,在sql中的两个表上保存一些条件