2

请多多包涵,因为我的 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来查找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

提前致谢!

4

1 回答 1

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 期保留的房间总数。如果您想要一个特定房间,您还可以将“AND a.id =”添加到您的 WHERE 子句中。

于 2013-02-19T05:22:22.303 回答