如何在 table 列中存储 SQL 查询结果

How to store SQL Query result in table column

我知道 INSERT INTO table_name QUERY;但是,我不确定在这种情况下如何才能达到预期的结果。

这里有一个稍微做作的例子来解释我要找的东西,但恐怕我不能把它说得更清楚。

我在为酒店设计的数据库中有两个 table。

预订CUSTOMER_BOOKING

其中BOOKING包含PK_room_number、room_type、等,CUSTOMER_BOOKING 包含 FK_room_number, FK_cusomer_id

CUSTOMER_BOOKING是一个链接table(很多客户可以做很多预订,很多预订可以包含很多客户)。

最终,在应用程序后端,我希望能够列出关联的客户少于 3 个的所有房间。我可以执行这个单独的查询并将结果保存在服务器端脚本中。

然而,更优雅的解决方案(从我的角度来看)是将其存储在 BOOKING table 本身中。即在CUSTOMER_BOOKING[=54=中增加一列no_of_bookings,统计当前PK_room_number作为外键FK_room_number出现的次数] table。为什么要这样做呢?因为我不可能编写一个复杂的查询,它既包括来自所有 ROOMS 的信息,以及其他 tables,还计算预订的发生次数,而不排除没有任何预订的 ROOMS .对于试图显示免费房间的酒店网站来说,这是一件非常糟糕的事情!

所以它看起来像这样

预订: PK_room_number (104B) room_type (双) room_price (高), no_of_bookings (3) 预订: PK_room_number (108C) room_type (单) room_price (低), no_of_bookings (1) CUSTOMER_BOOKING:FK_room_number (104B) FK_customer_id (4312) CUSTOMER_BOOKING: FK_room_number (104B) FK_customer_id (6372) CUSTOMER_BOOKING: FK_room_number (104B) FK_customer_id (1112) CUSTOMER_BOOKING: FK_room_number (108C) FK_customer_id (9181)

我将如何创建这个?

以下生成一个列表,显示所有预订,如果房间的每个房间都有客户,则标记为 0 或 1。如果有多个客户,它会多次显示一些房间。

select 预订中。*, case CUSTOMER_BOOKING.FK_ROOM_NUMBER 为 null THEN 0 ELSE 1 END AS BOOKING_FLAG 来自 BOOKING LEFT OUTER JOIN CUSTOMER_BOOKING ON BOOKING.PK_room_numer = CUSTOMER_BOOKING.FK_room_number

总结和分组我们得出:

select 预订中。*, SUM(case when CUSTOMER_BOOKING.FK_ROOM_NUMBER is null THEN 0 ELSE 1 END) AS BOOKING_COUNT 来自 BOOKING LEFT OUTER JOIN CUSTOMER_BOOKING ON BOOKING.PK_room_number = CUSTOMER_BOOKING.FK_room_number 分组依据 BOOKING.PK_room_number

我能想到至少两个其他解决方案...

Because it would be impossible for me to write a single complicated query which will both include the information from all ROOMS, among other tables, and also count the occurrences of bookings, without excluding ROOMS that don't have any bookings.

我不会说这是不可能的,除非您 运行 遇到性能问题,否则它比添加新的摘要列更容易实施:

select b.*, count(cb.room_number) 
from bookings b
left join customer_booking cb on b.room_number = cb.room_number
group by b.room_number

根据您的查询,可能需要使用派生的 table 代替每个房间的预订数

select b.*, coalesce(t1.number_of_bookings,0) number_of_bookings
from bookings b
left join (
    select room_number, count(*) number_of_bookings
    from customer_booking
    group by room_number
) t1 on t1.room_number = b.room_number

您必须 left join 派生 table 和 select coalesce(t1.number_of_bookings,0) 以防房间在派生 table 中没有任何条目(即0 个预订)。

当您运行遇到每次计算预订数量的性能问题时,摘要列是个好主意。在这种情况下,我建议在 customer_booking table 上创建 insertdelete 触发器,以增加或减少 number_of_bookings 列。

你可以像这样 select 直接完成:

select DISTINCT 
       b1.room_pk,
       c1.no_of_bookings
  from cust_bookings b1,
       (select room_pk, count(1) as no_of_bookings
          from cust_bookings
         group by room_pk) c1
 where b1.room_pk = c1.room_pk 
 having c1.no_of_bookings < 3

抱歉,我使用了我自己的 table 名称来测试它,但你应该很容易弄明白。此外,"having" 行仅用于限制返回到少于 3 个预订的房间的行。如果您删除该行,您将获得所有内容,并且可以使用相同的 sql 更新预订中的列 table 如果您仍想走那条路线。

考虑以下解决方案。

一个简单的聚合查询来计算每次预订的客户:

SELECT b.PK_room_number, Count(c.FK_customer_id) 
FROM Booking b
INNER JOIN Customer_Booking c ON b.PK_room_number = c.FK_room_number
GROUP BY b.PK_room_number
HAVING Count(c.FK_customer_id) < 3;  # ADD 3 ROOM MAX FILTER

如果您打算使用新列 no_of_booking,这里是一个更新查询(使用聚合子查询)到 运行 在从 Web 前端插入新值之后:

UPDATE Booking b 
INNER JOIN 
  (SELECT b.PK_room_number, Count(c.FK_customer_id) As customercount
   FROM Booking b
   INNER JOIN Customer_Booking c ON b.PK_room_number = c.FK_room_number
   GROUP BY b.PK_room_number) As r
ON b.PK_room_number = r.PK_room_number
SET b.no_of_booking = r.customercount;