Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 技巧:与行值的左连接关系_Mysql_Join - Fatal编程技术网

Mysql 技巧:与行值的左连接关系

Mysql 技巧:与行值的左连接关系,mysql,join,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 m

假设我有以下两个表:

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

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


非常感谢您对如何解决此问题的任何想法/意见/帮助。

您应该创建一个表,在该表中,每个房间的人数从1人到最多人,以及房间id。然后您可以进行外部连接,并按照您的要求获取信息

您还可以将其创建为一个临时表,用代码中所需的数据构造查询

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)

正如abresas的回答和xQbert的评论所表明的,您需要以某种方式创建数据,以便将其与表连接起来

像abresas的回答一样,我使用了一个辅助表,但在我的解决方案中,这个表只需要填写数字1到N,其中N=列
max\u people
上可能出现的最大值

我用一列
num
创建了一个名为
aux
的辅助表。此查询适用于我:

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
选择(price.price为空,0,price.price)作为价格,room.room\u no,aux.num作为\u人员的nr\u
从房间

JOIN aux ON aux.num您当前使用的SQL语句是什么?这是我在数据库中实际使用的SQL语句的一个非常简化的子集。这是酒店预订应用程序的一部分,在该应用程序中,我使用数据透视表样式的数据网格中的不同参数定义每个房间的价格。因此,我不能为这一部分提供任何实际的查询,因为我目前没有。我很欣赏代码90,但是如果您不能给出一个实际的查询示例,那么我们就不能提供一个实际的解决方案:-)这是一种从任何地方生成数据的尝试。例如,在102房间,价格为0的1人的nr_将很难实现,因为没有记录。使用左,右,甚至全外将只给你1和3。因此,您需要一张数字为1到X的桌子,其中X是房间允许的最大人数,或者,您必须建立一种方法,以允许以某种方式生成这些缺失的数字,以便根据需要将其加入。现在,您可能能够解决此问题的创造性方法是:在“从房间中选择不同的Max_人员”上创建子集/视图。如果生成的列表始终包含1到x,其中x是max of max_people(无间隙),则可以使用此子查询获取缺少的记录,并将其用作交叉联接的左侧部分。它的神奇之处在于无处生成数据。嗨,abresas,非常感谢你的时间和帮助。这很好,但它需要我为每个房间输入最大数量的数字,这实际上是可以的,但Jong Bor的解决方案更适合,因为它只需要在表中输入非分类顺序编号。无论如何,谢谢你。嗨,Jong-Bor,这非常有效,似乎是适合我这种情况的最佳方法。我非常感谢您的帮助,一旦我成功地将其实现到我的实际代码中,我会将其标记为已接受。谢谢在为此苦苦挣扎了好几个小时却没有取得任何成功后,不得不看到整个桌子按照预期的方式工作,这让我松了一口气:))再次感谢。。
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 [...]