如何在表列

时间:2015-08-01 14:37:42

标签: mysql sql calculated-columns

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

这是一个有点人为的例子来解释我正在寻找的东西,但我担心我不能更加成功。

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

预订 CUSTOMER_BOOKING

预订包含 PK_room_number,room_type,等, CUSTOMER_BOOKING 包含 FK_room_number,FK_cusomer_id

CUSTOMER_BOOKING 是一个链接表(许多客户可以进行多次预订,许多预订可以包含许多客户)。

relationship

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

然而,更优雅的解决方案(从我的角度来看)是将其存储在 BOOKING 表中。即添加一列no_of_bookings,用于计算当前PK_room_number在 CUSTOMER_BOOKING 表中显示为外键FK_room_number的次数。为什么这样呢?因为我不可能编写一个复杂的查询,其中既包括来自所有房间的信息,也包括其他表格,并且还计算预订的发生次数,而不排除没有任何预订的房间。试图展示免费房间的酒店网站是一件非常糟糕的事情!

所以它看起来像这样

预订:PK_room_number(104B)room_type(double)room_price(high),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)

我将如何创建这个?

4 个答案:

答案 0 :(得分:1)

  

因为我不可能写一个复杂的   查询将包括来自所有ROOMS的信息   其他表,也计算预订的发生,没有   不包括没有任何预订的房间。

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

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

根据您的查询,可能需要使用包含每个房间的预订计数的派生表,而不是

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派生表并选择coalesce(t1.number_of_bookings,0),以防房间在派生表中没有任何条目(即0个预订)。

当您遇到每次计算预订数量的性能问题时,汇总列是一个好主意。在这种情况下,我建议在insert表上创建deletecustomer_booking个触发器,以递增或递减number_of_bookings列。

答案 1 :(得分:1)

你可以在一个单一的直接选择中这样做:

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

抱歉,我使用自己的表名来测试它,但你应该很容易弄明白。此外,“有”行仅用于限制返回到少于3次预订的房间的行。如果您删除该行,您将获得所有内容,如果您仍想使用该路径,可以使用相同的sql更新预订表上的列。

答案 2 :(得分:1)

考虑以下解决方案。

一个简单的聚合查询,用于计算每次预订的客户数量:

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;

答案 3 :(得分:0)

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

选择预订。*, case CUSTOMER_BOOKING.FK_ROOM_NUMBER为null然后0结束1结束作为预订_FLAG 从BOOKING LEFT OUTER JOIN CUSTOMER_BOOKING ON BOOKING.PK_room_numer = CUSTOMER_BOOKING.FK_room_number

总结和分组我们到达:

选择预订。*, SUM(CUSTOMER_BOOKING.FK_ROOM_NUMBER为空,然后0 ELSE 1 END)AS BOOKING_COUNT 从BOOKING LEFT OUTER JOIN CUSTOMER_BOOKING ON BOOKING.PK_room_number = CUSTOMER_BOOKING.FK_room_number GROUP BY BOOKING.PK_room_number

我至少还有其他两种解决方案可以让我想到......