简体   繁体   English

跨越三个表的SQL查询

[英]SQL query spanning three tables

Bear with me please because my SQL is not that good. 请耐心等待,因为我的SQL不好。

I want to write a query that takes into consideration information from 3 different tables. 我想编写一个查询,其中考虑了来自3个不同表的信息。

Let me explain the situation: When a customer books a room, they have the preference of several rooms and the rooms can be booked on individual days (one unique booking has to be made per day) at different times. 让我解释一下这种情况:当客户预订一个房间时,他们会优先选择几个房间,并且这些房间可以在不同的日期(每天必须进行一次唯一的预订)进行预订。

I now want to write a query that will check if a room is available on a certain time of the day. 现在,我想编写一个查询,以检查一天中特定时间是否有房间。 These are the tables I have on my database 这些是我数据库中的表

room 房间

This table stores information about each room 该表存储有关每个房间的信息

Fields:

id (primary key)
capacity    
img 
notes   
building_id 
roomstructure_id    
lecturestyle_id

request 请求

This table stores message about each request made 该表存储有关每个请求的消息

Fields

id (primary key)
day_id
period_id
preference_id (foreign key from preference.id)

This table stores information about each request made. 该表存储有关每个请求的信息。

preference 偏爱

This table stores information about all the room preferences. 该表存储有关所有房间偏好的信息。

id (PK)      
request_id (foreign key from request.id)      
room_id (foreign key from room.id)

I hope what I am trying to do has become apparent. 我希望我想做的事情变得显而易见。

If for example I am checking whether room C233 is booked on Monday, 09:00 - I would need to look up the room information in the room table and then use the room_id in the preference table to look up the request_id . 例如,如果我要检查房间C233是否在星期一的09:00预订,则需要在房间表中查找房间信息,然后在首选项表中使用room_id来查找request_id

Once I have the request_id which has been linked to a specific room (in the room preference table) I can see whether day_id=1 and period_id=1 in the request table. 一旦有了已链接到特定房间的request_id (在房间偏好表中),我就可以在请求表中看到day_id = 1和period_id = 1。 If day_id=1 and period_id=1 then it means that the room is booked at Monday, 09:00. 如果day_id = 1和period_id = 1,则表示该房间在星期一09:00预订。

This means that room is not available so it isn't counted but if this row could not be found then it would be counted. 这意味着房间不可用,因此不计入房间,但是如果找不到此行,则将计入房间。

This is the SQL I've written so far - its very simple but it doesn't do everything I want it to do: 这是我到目前为止编写的SQL-非常简单,但是并不能满足我的要求:

SELECT COUNT(*) totalCount FROM ts_room

In addition to this, I have been offered advice on another forum - this code here. 除此之外,还为我提供了另一个论坛的建议-此处的代码。 But it doesn't work at all. 但这根本不起作用。 I don't think it meets my criteria: 我认为它不符合我的标准:

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

Thanks in advance! 提前致谢!

OK, that code you posted is close to correct, but has a couple of problems. 好的,您发布的代码接近正确,但是存在一些问题。 First, there's an inconsistency in your name for the request table. 首先,您的请求表名称不一致。 In your description you just call it 'request', but in the code it's 'ts_request'. 在描述中,您仅将其称为“ request”,但在代码中则为“ ts_request”。 Might just be a typo in your question though. 可能只是您的问题中的错字。

The other issue is that the keys in your second INNER JOIN (between preference and request) are mixed up. 另一个问题是第二个INNER JOIN(在首选项和请求之间)中的键是混杂的。 You have b.request_id = c.preference_id. 您有b.request_id = c.preference_id。 IE: you're trying to match the two foreign keys up with each other, rather than with the primary keys that they represent. IE:您正在尝试使两个外键相互匹配,而不是与它们所代表的主键匹配。 You only need one primary/foreign key pair to do the join. 您只需要一个主/外键对即可进行联接。 So this should work (not tested): 所以这应该工作(未经测试):

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

(I'm not a fan of using totally non-descriptive identifiers a, b, and c, but it's valid code. Personally I would at least use rm, rq, pf, or something identifiable like that. Or even just stick with the table names since they're fairly short anyway.) (我不喜欢使用完全非描述性的标识符a,b和c,但是它是有效的代码。就我个人而言,我至少会使用rm,rq,pf或类似的可识别名称。或者甚至坚持使用表名,因为它们总是很短。)

One thing to note is that having foreign keys in both directions from the request and preferences tables means there is exactly one preference per request. 要注意的一件事是,在请求和首选项表的两个方向上都具有外键意味着每个请求恰好有一个首选项。 (Or possibly zero if the preference_id field in the request table can be left blank/null.) If you intended it to be possible for there to be multiple preferences submitted per request, that preference_id foreign key column should be removed, since it's not a unique value. (如果请求表中的preference_id字段可以留为空白/空,则可能为零。)如果您希望每个请求都可以提交多个首选项,则应该删除那个preference_id外键列,因为它不是独特的价值。 It's also not required for the above query, although if indeed there is indeed a limitation of one preference per request, it's obviously possible you've included it for use somewhere else. 上面的查询也不是必需的,尽管如果确实确实每个请求都有一个首选项的限制,则很可能您已将其包含在其他地方。

Edit: As mentioned in the comments on your question, this query also doesn't look for a specific room, but rather returns the total number of rooms reserved for day 1, period 1. If you want a specific room, you would also have to add "AND a.id = " to your WHERE clause. 编辑:如您对问题的评论中所述,此查询也不会查找特定的房间,而是返回为第一天的时段1保留的房间总数。如果您想要一个特定的房间,您还将拥有在您的WHERE子句中添加“ AND a.id =”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM