简体   繁体   中英

selecting the minimum amount records where the sum is greater than a certain number

I'm trying to put together a query that for a restaurant reservation system. The idea is that if there is no table big enough to sit the party size then to look through the other free tables and find two tables big enough to be put together to accommodate the party size.

Ideally I would like to be able to select the minimum of tables to as closely match the size of the party.

For example if there is a request for a table of twelve I would like to ideally find two of the tables for six and no more.

This is the query I've tried but it gives an empty result

select tbl_id, sum(max_seats) as sumseats from tbl_list 
group by tbl_id having sumseats> 11

I have put a link to sql fiddle to show the table structure

http://sqlfiddle.com/#!2/5a6904/2/0

Try something like the following(You'll require something like PHP in addition to MySQL):

  1. Check if a single table can seat the required number of people. If yes, print all the such tables in ascending order of capacity.
  2. If no single table has capacity greater than or equal to the required capacity, reserve the table with highest capacity and deduct the capacity from the required capacity.
  3. Goto step 1.

Code :

$bookedTables = array();
while ($requiredCapacity > 0) {
    $query = "SELECT * FROM (SELECT tbl_id, max_seats FROM tbl_list WHERE max_seats > $requiredCapacity)table1 ORDER BY table1.max_seats ASC";
    $result = mysql_query($query);
    if (count($result)!=0) {
        array_push($bookedTables, $result[0]['tbl_id'];
        $requiredCapacity = $requiredCapacity - $result[0]['max_seats'];
    }
    else {
        $query = "SELECT * FROM (SELECT tbl_id, max_seats FROM tbl_list)table1 ORDER BY table1.max_seats DESC";
        if (count($result)!=0) {
            array_push($bookedTables, $result[0]['tbl_id'];
            $requiredCapacity = $requiredCapacity - $result[0]['max_seats'];
        }
        else {
            echo "No more tables left";
            break;
        }
    }
}

I'm not proposing this as a definitive answer, but it's something to think about...

SELECT * FROM tables;
+----+------+
| id | size |
+----+------+
|  1 |    2 |
|  2 |    2 |
|  3 |    2 |
|  4 |    2 |
|  5 |    4 |
|  6 |    4 |
|  7 |    4 |
|  8 |    6 |
|  9 |    6 |
| 10 |    8 |
+----+------+

 SELECT *
     , x.size + y.size + z.size pax 
  FROM tables x 
  LEFT 
  JOIN (SELECT * FROM tables UNION SELECT 0,0) y 
    ON y.size < x.size OR (y.size = x.size AND y.id < x.id) 
  LEFT 
  JOIN (SELECT * FROM tables UNION SELECT -1,0) z 
    ON z.size < y.size OR (z.size = y.size AND z.id < y.id)
HAVING pax >= 12 
 ORDER 
    BY pax
     , x.size DESC
     , y.size DESC
     , z.size DESC
 LIMIT 1;
+----+------+------+------+------+------+------+
| id | size | id   | size | id   | size | pax  |
+----+------+------+------+------+------+------+
| 10 |    8 |    7 |    4 |   -1 |    0 |   12 |
+----+------+------+------+------+------+------+

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM