假设我有以下两个表:
PRICE
price_id price room_id nr_of_people
1 80 1 1
2 75 1 2
3 90 2 2
4 120 3 3
ROOM
room_id room_no max_people
1 101 2
2 102 3
3 103 4
而且,我需要以下结果:
QUERY_RESULT
price room_no nr_of_people
80 101 1
75 101 2
0 102 1
90 102 2
0 102 3
0 103 1
0 103 2
120 103 3
0 103 4
这里棘手的部分是,我需要检索每个人的价格(2人,3人,4人;这是增加到房间表中定义的max_people
,如果有的话价格表中没有实际数据,默认情况下应填写0。上图应该支持我的解释。
我不确定表结构是否有任何逻辑错误。
非常感谢有关如何解决问题的任何想法/输入/帮助。
答案 0 :(得分:1)
您应该创建一个表,其中每个房间都有1到max_people的nr_of_people,以及room_id。然后你可以按照你的要求进行OUTER JOIN获取信息。
您还可以将其创建为临时表,使用代码中所需的数据构建查询。
mysql> CREATE TEMPORARY TABLE nr ( nr_of_people int, room_id int );
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT INTO nr VALUES ( 1, 1 ), ( 2, 1 ), ( 1, 2 ), ( 2, 2 ),
( 3, 2 ), ( 1, 3 ), ( 2, 3 ), ( 3, 3 ), ( 4, 3 );
Query OK, 9 rows affected (0.00 sec)
Records: 9 Duplicates: 0 Warnings: 0
mysql> SELECT price.price, room.room_no, nr.nr_of_people
FROM price
RIGHT OUTER JOIN nr ON price.room_id = nr.room_id AND price.nr_of_people = nr.nr_of_people
INNER JOIN room ON nr.room_id = room.room_id;
+-------+---------+--------------+
| price | room_no | nr_of_people |
+-------+---------+--------------+
| 80 | 101 | 1 |
| 75 | 101 | 2 |
| NULL | 102 | 1 |
| 90 | 102 | 2 |
| NULL | 102 | 3 |
| NULL | 103 | 1 |
| NULL | 103 | 2 |
| 120 | 103 | 3 |
| NULL | 103 | 4 |
+-------+---------+--------------+
9 rows in set (0.00 sec)
答案 1 :(得分:1)
作为abresas的回答和xQbert的评论建议,你需要创建数据才能将它与你的表连接起来。
与abresas的答案一样,我使用辅助表,但在我的解决方案中,此表需要仅填充数字1到N,其中N =可以出现在max_people
列上的最大值。< / p>
我创建了一个名为aux
的辅助表,其中包含一列num
。此查询适用于我:
SELECT IF(price.price IS NULL, 0, price.price) AS price, room.room_no, aux.num AS nr_of_people
FROM room
JOIN aux ON aux.num <= room.max_people
LEFT JOIN price ON ( price.room_id = room.room_id
AND aux.num = price.nr_of_people )
ORDER BY room.room_id, num
不幸的是,mysql没有提供生成整数序列的本机机制(参见these questions),所以物理创建辅助表似乎是实现你的最实用的方法需要,虽然如果你真的不能或不想创建这样的表,确实存在变通方法。
只是为了它的乐趣,以下内容可以在不创建新表的情况下工作(所有这些都受到我所链接的问题的启发):
SELECT [...]
FROM room
JOIN (
SELECT 1 num
UNION SELECT 2
UNION SELECT 3
UNION SELECT 4
-- ...add as many entries as needed...
) aux ON aux.num <= room.max_people
LEFT JOIN [...]
以及:
SELECT [...]
FROM room
JOIN (
SELECT @row := @row +1 AS num
FROM any_table_that_is_big_enough, (SELECT @row :=0) r
) aux ON aux.num <= room.max_people
LEFT JOIN [...]