将关系代数转换为相应的SQL查询



我正在努力了解如何正确地从关系代数转换为SQL查询

我发现这是我很难转换的事情之一。有人能分享一些技巧吗?

表格:

Room(_roomId_, numberOfBeds, price)
Guest(_guestId_, homeTown, age)
Reservation(_roomId_, _guestId_, date)

关系代数:

Πprice(ΠroomId(ΠguestId(σage<20)Guest) Natural Join Reservation) Natural Join Room

查询:我设法从声明的一部分推断出以下内容:

SELECT roomId FROM (SELECT guestID from Guest WHERE age<20) Natural Join Reservation

我接近了吗?

有几种方法可以解决这个问题。如果你比关系代数更熟悉数据库,第一个选项可能更容易,而如果你熟悉关系代数,第二个选项会更容易(对于更复杂的问题更准确)。

表格优先:

从计算连接开始。您知道您有三个集合(表)GuestReservationRoom,这三个集合都是自然联接的(内部联接的)。所以你可以开始写这样的查询:

SELECT *
FROM Guest g
    INNER JOIN Reservation res
        ON g._guestId_ = res._guestId_
    INNER JOIN Room r
        ON res._roomId_ = r._roomId_;

一旦完成,应用您的条件:

SELECT *
FROM Guest g
    INNER JOIN Reservation res
        ON g._guestId_ = res._guestId_
    INNER JOIN Room r
        ON res._roomId_ = r._roomId_
WHERE g.age < 20;

或者,您可以将g.age的条件放在与Reservation的联接中,但建议将条件放在INNER JOINWHERE子句中。

最后,填充SELECT:

SELECT g._guestId_,
    res._roomId_,
    r.price
FROM Guest g
    INNER JOIN Reservation res
        ON g._guestId_ = res._guestId_
    INNER JOIN Room r
        ON res._roomId_ = r._roomId_
WHERE g.age < 20;

操作顺序

为此,您可以使用操作顺序编写查询。所以括号内的所有内容都会先执行。通过这种方式,您可以从针对Guest:编写查询开始

SELECT g._guestId_
FROM Guest g
WHERE g.age < 20;

下一个集合将是Reservations,这是自然连接的:

SELECT g._guestId_,
    res._roomId_
FROM Guest g
    INNER JOIN Reservation res
        ON g._guestId_ = res._guestId_;

最后,你来到Room集合,再次自然加入:

SELECT g._guestId_,
    res._roomId_,
    r.price
FROM Guest g
    INNER JOIN Reservation res
        ON g._guestId_ = res._guestId_
    INNER JOIN Room r
        ON res._roomId_ = r._roomId_
WHERE g.age < 20;

应该是这样的。。

SELECT price, _roomId_ FROM room 
inner join Reservation on (reservation._roomId_ = room._roomId_
inner join Guest  on (reservation._guestId = guest._guestId and age <20) ;

在你的关系代数表示法中,你有priceroomId的项目(选择),那么你就有了Guest and Reservation之间的自然连接和这个笛卡尔乘积and Room之间的自然联系。。自然联接在sql中由关系两侧主键上的内部联接来表达。。最后你在guest age上有一个条件,这是一个由where子句管理的条件,或者直接在连接条件中添加and子句

最新更新