棘手:与行值的左连接关系

时间:2012-02-19 16:17:55

标签: mysql join

假设我有以下两个表:

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。上图应该支持我的解释。

我不确定表结构是否有任何逻辑错误。

非常感谢有关如何解决问题的任何想法/输入/帮助。

2 个答案:

答案 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 [...]