【问题标题】:Get the most popular result from theses tables从这些表格中获取最受欢迎的结果
【发布时间】:2016-08-17 16:44:37
【问题描述】:

这是我的表定义:

表___房间:

|--------|-----------|--------|----------|
|ROO_Id  |ROO_HotelId|ROO_Name|ROO_Number|
|--------|-----------|--------|----------|
|       1|AAA00      |Room 12 |        12|
|       2|AAA00      |Room 14 |        14|
|       3|AAA00      |Room 16 |        16|
|       4|ZZZ99      |Room 11 |        11|
|       5|ZZZ99      |Room 22 |        22|
|       6|ZZZ99      |Room 33 |        33|
|--------|-----------|--------|----------|

表___预订:

|--------|-----------|----------|
|BOO_Id  |BOO_HotelId|BOO_RoomId|
|--------|-----------|----------|
|       1|AAA00      |         1|
|       2|AAA00      |         1|
|       3|AAA00      |         3|
|       4|ZZZ99      |         5|
|       5|ZZZ99      |         5|
|       6|ZZZ99      |         5|
|--------|-----------|----------|

其实我有:

  • AAA00 的预订数量 = 3

  • AAA00 的房间数 = 3


我想仅列出 AAA00 属性的房间,并按预订数量中最受欢迎的房间对其进行排名。

所以我使用这个查询:

SELECT r.ROO_Number BOO_RoomId, 
  ( ( ifnull(cnt_book,0)*100)/(SELECT count(*) FROM ___Bookings)) percentage, 
  ifnull(cnt_book,0) `count` 
FROM ___Rooms r 
   LEFT JOIN (
               SELECT BOO_RoomId, count(*) cnt_book 
               FROM ___Bookings 
               WHERE BOO_HotelId='AAA00' 
               GROUP BY BOO_RoomId
             ) cnt ON r.ROO_Id=cnt.BOO_RoomId 
ORDER BY percentage DESC

这个查询的预期结果是:

  • 1 - 房间 2 - 2 次预订 - 66.66%

  • 2 - 房间 3 - 1 次预订 - 33.33%

  • 3 - 房间 2 - 0 预订 - 00.00$

但它会将所有房间都归还给我。

你能帮我解决这个问题吗?

谢谢。

【问题讨论】:

    标签: php mysql sql


    【解决方案1】:

    解决方案

    使用CASESUM 将每个房间的所有预订加在一起。然后,JOIN 进行子查询,使酒店总预订量可用于每一行。

    SELECT r.ROO_Name
         , Sum(CASE WHEN BOO_id IS NULL THEN 0 ELSE 1 END) NumBookings
         , Concat(
             Format(
               Sum(CASE WHEN BOO_id IS NULL THEN 0 ELSE 1 END) 
               / TotalBookings 
               * 100
             , 0)
           , '%') AS PercentageTotal
      FROM (  __Rooms r LEFT JOIN __Bookings b ON r.ROO_Id = b.BOO_RoomId
           ) INNER JOIN (SELECT BOO_HotelId
                              , Count(*) AS TotalBookings
                           FROM __Bookings 
                          GROUP BY BOO_HotelId
                        ) AS TotalHotelBookings 
                     ON r.ROO_HotelId = TotalHotelBookings.BOO_HotelId
     WHERE r.ROO_HotelId = 'AAA00'
     GROUP BY r.ROO_Name
     ORDER BY r.ROO_Name
    ;
    

    结果集

    ROO_Name  NumBookings  PercentageTotal
    --------  -----------  ---------------
    Room 12             2              67%
    Room 14             0               0%
    Room 16             1              33%
    

    关键点

    Sum(CASE WHEN BOO_id IS NULL THEN 0 ELSE 1 END)

    【讨论】:

    • 嗯...谢谢,但我有这个错误:Warning: Division by zero.
    • 我想如果因为TotalBookings 在我的真实数据库中返回0 和一些数据。请问在这种情况下我怎么能有条件?
    【解决方案2】:

    差不多应该是这样的:

    SELECT
        foo.ROO_Id,
        foo.ROO_Name, 
        foo.cnt, 
        (foo.cnt * 100.0) / (SELECT count(*) FROM ___Bookings WHERE BOO_HotelId = foo.ROO_HotelId) AS percentage
    FROM (
        SELECT
            ROO_Id,
            ROO_Name,
            ROO_HotelId,
            (SELECT count(*) FROM ___Bookings b WHERE b.BOO_RoomId = r.ROO_Id) AS cnt
        FROM ___Rooms r
        WHERE ROO_HotelId = 'AAA00'
    ) AS foo
    ORDER BY cnt DESC
    

    【讨论】:

    • 该查询在 PostgreSQL 上运行良好。如果你在任何地方都得到 100%,那一定是一些四舍五入的问题。尝试 CAST(count(*) * 100.0 AS float) 或添加括号。
    猜你喜欢
    • 1970-01-01
    • 2019-09-09
    • 1970-01-01
    • 1970-01-01
    • 2020-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多