如何使用嵌套的内连接语句?

时间:2016-02-03 23:54:27

标签: sqlite

我创建了三个表:

CREATE TABLE guest(

name varchar(100),
ranking int,
PRIMARY KEY (name)
);

CREATE TABLE room(

 roomname varchar(100),
 wallcolor varchar(100),
 rating int,
 PRIMARY KEY(roomnane)
 );

 CREATE TABLE reservation(

 name varchar(100),
 roomname varchar(100),
 day varchar(100),
 moveinday int,
 moveoutday int,
 PRIMARY KEY(roomname, day, start, finish),
  FOREIGN KEY(roomname) REFERENCES room(roomname),
  FOREIGN KEY(name) REFERENCES guest(name)
 );

我正在尝试编写DELETE查询以删除所有不符合租用任何房间的客人。有资格租赁意味着客人排名大于或等于房间排名。几乎删除预订条目,如果他们不符合条件,也删除客人

我试过

 DELETE 
 FROM
 reservation, guest
 INNER JOIN (
 SELECT
    reservation.roomname,
    reservation.day,
    reservation.start,
    reservation.finish
FROM
    guest
INNER JOIN reservation ON reservation.name = guest.name
INNER JOIN room ON reservation.roomname = room.roomname
WHERE
    room.rating > guest.ranking 
) invalidReservationTable  
ON reservation.roomname = invalidReservationTable.roomname
AND reservation.day = invalidReservationTable.day
AND reservation.start = invalidReservationTable.start
AND reservation.finish = invalidReservationTable.finish;

我在FROM保留行之后的Inner Join语句上的sqlite上运行此错误时收到错误。我究竟做错了什么?我是否正确地删除了预订?

1 个答案:

答案 0 :(得分:0)

您无法从同一语句中的多个表中删除。考虑分成两个动作查询:首先在reservations表上由于外键约束,然后在guests表上,添加一个符合您需求的WHERE子句子查询。

首先,保留删除:

DELETE FROM reservation
WHERE name IN 
  (SELECT reservation.name 
   FROM guest 
   INNER JOIN reservation ON reservation.name = guest.name 
   INNER JOIN room ON reservation.roomname = room.roomname        
   WHERE room.rating > guest.ranking);

然后客人表删除。但是,之前每个查询将不再存在来宾的相应预留。因此,您现在应该删除访客,而无需使用LEFT JOIN...NULL处理任何预订。

DELETE FROM guest 
WHERE name IN 
  (SELECT guest.name 
   FROM guest 
   LEFT JOIN reservation ON reservation.name = guest.name 
   WHERE reservation.name IS NULL)

顺便说一下,重新考虑这里的设计。在一对多关系中,多对多表应该是唯一的删除交互。不应定期清理客人(可能会进行预订)。并且在预订之前让您的应用/脚本验证排名/评级。