请耐心等待我,因为我的SQL不太好。
我想编写一个考虑来自3个不同表的信息的查询。
让我解释一下这种情况:当客户预订房间时,他们会偏好几个房间,并且可以在不同时间预订房间(每天必须预订一次)。
我现在想写一个查询,检查一天中的特定时间是否有空房。这些是我在数据库中的表格
室
此表存储有关每个房间的信息
Fields:
id (primary key)
capacity
img
notes
building_id
roomstructure_id
lecturestyle_id
请求
此表存储有关每个请求的消息
Fields
id (primary key)
day_id
period_id
preference_id (foreign key from preference.id)
此表存储有关每个请求的信息。
偏好
此表存储有关所有房间偏好的信息。
id (PK)
request_id (foreign key from request.id)
room_id (foreign key from room.id)
我希望我想要做的事情变得明显。
例如,如果我正在检查C233是否在星期一09:00预订,我需要在房间表中查找房间信息,然后使用 room_id < / strong>在首选项表中查找 request_id 。
一旦我将 request_id 链接到特定房间(在房间首选项表中),我就可以看到day_id = 1和period_id = 1 请求表。如果day_id = 1且period_id = 1则表示该房间在星期一09:00预订。
这意味着房间不可用,所以不计算,但如果找不到这一行,那么它将被计算在内。
这是我到目前为止所编写的SQL - 它非常简单,但它不能完成我想要它做的所有事情:
SELECT COUNT(*) totalCount FROM ts_room
除此之外,我还获得了另一个论坛的建议 - 这里的代码。但它根本不起作用。我不认为它符合我的标准:
SELECT COUNT(*) totalCount
FROM room a
INNER JOIN preference b
ON a.id = b.room_id
INNER JOIN ts_request c
ON b.request_id = c.preference_id
WHERE c.day_id = 1 AND c.period_id = 1
提前致谢!
答案 0 :(得分:0)
好的,您发布的代码接近正确,但有几个问题。首先,请求表的名称不一致。在您的描述中,您只需将其称为“请求”,但在代码中它是“ts_request”。可能只是你问题上的拼写错误。
另一个问题是第二个INNER JOIN中的键(首选项和请求之间的键)混淆了。你有b.request_id = c.preference_id。 IE:您尝试将两个外键相互匹配,而不是使用它们所代表的主键。您只需要一个主/外键对来进行连接。所以这应该有效(未经测试):
SELECT COUNT(*) totalCount
FROM room a
INNER JOIN preference b
ON a.id = b.room_id
INNER JOIN request c
ON b.request_id = c.id
WHERE c.day_id = 1 AND c.period_id = 1
(我不喜欢使用完全非描述性的标识符a,b和c,但它是有效的代码。我个人至少会使用rm,rq,pf或类似的东西。甚至只是坚持使用表名,因为它们相当短。)
需要注意的一点是,在请求和首选项表的两个方向上都有外键意味着每个请求只有一个首选项。 (如果请求表中的preference_id字段可以留空/空,则可能为零。)如果您希望每个请求可以提交多个首选项,则应删除该preference_id外键列,因为它不是独特的价值。上述查询也不需要它,但如果确实确实每个请求确实存在一个首选项的限制,那么显然有可能将其包含在其他地方使用。
编辑:如您对问题的评论中所述,此查询也不会查找特定房间,而是返回为第1天(第1期)预留的房间总数。如果您想要特定房间,则为还必须在WHERE子句中添加“AND a.id =”。