通过联接更新SQL表格?

4
我有以下数据库,希望更新“room”表。表“room”列出了单人、双人或大床房型,价格是每晚每间房的价格,酒店名称是酒店的名称。
我需要做的是将Scotty Hotel中所有双人房改为大床房,并将其价格增加10%。
我知道如何在单个表中更新价格和类型,但似乎在这里我需要通过HNO连接hotel和room,然后进行更新。可能需要使用嵌套查询?
create table Hotel  (
   HNo char(4),
   Name varchar(20)   not null,
   Address varchar(50),
   Constraint PK_Hotel Primary Key (HNo)
);

create table Room  (
   RNo char(4),
   HNo char(4),
   Type char(6) not null,
   Price decimal (7,2),
   Constraint PK_Room Primary Key (HNo, RNo),
   Constraint FK_Room Foreign Key (HNo)
   references Hotel (HNo)
);


create table Guest  (
   GNo char(4),
   Name varchar(20) not null,
   Address varchar(50),
   Constraint PK_Guest Primary Key (GNo)

);

create table Booking   (
   HNo char(4),
   GNo char(4),
   DateFrom date,
   DateTo date,
   RNo char(4),
   Constraint PK_Booking Primary Key (HNo, GNo, DateFrom),
   Constraint FK_Booking Foreign Key (GNo)
   references Guest (GNo),
   Constraint FK_Booking_room Foreign Key (HNo, RNo)
   references Room (HNo, RNo),
   Constraint FK_Booking_hotel Foreign Key (HNo)
   references Hotel (HNo)
);

我有两个主要问题:

  1. 是否可以更新需要联接的表?

  2. 我想通过视图列出客人。我能否创建一个包含酒店名称和曾经入住过该酒店的不同客人数量的视图?


2
你正在使用哪个RDBMSRDBMS代表关系数据库管理系统RDBMS是SQL的基础,也是所有现代数据库系统如MS SQL Server、IBM DB2、Oracle、MySQL等的基础。 - John Woo
你的代码中有多个错误,以至于我无法快速构建一个SQL Fiddle来帮助你解决问题。例如,在create table Hotel的末尾有一个额外的闭合括号) - Sepster
@Sepster 你看到了什么错误?除了缺少分号这一点,在某些数据库管理系统中不是必需的,我没有看到其他问题。 - ypercubeᵀᴹ
@ypercube 我最初没有在遇到的第一个问题之外进行调试,但后来发现只是缺少了 ;。我必须承认,我假设使用的是 mySql。已编辑代码以反映出这一点 - 我添加了 ;,因为我相信虽然它们并非普遍所需,但它们几乎被广泛接受了?(如果不是这种情况,请重新编辑) - Sepster
2个回答

11

首先,建议进行选择以确保您的搜索/筛选条件正确:

SELECT
  h.Name,
  r.RNo,
  r.Type,
  r.Price

FROM
  room r

  INNER JOIN hotel h
  on h.hno = r.hno

WHERE
  h.name = 'Scotty Hotel'
  and
  r.type = 'Double' ;

如果这个条件过滤了正确的行,那么就使用同样的过滤条件执行一个更新查询。提示:复制整个SELECT查询并进行编辑以形成新的UPDATE查询。例如,在MySQL中,将FROM替换为UPDATE(保留原始FROM子句的内容),保留WHERE不变,并使用原始查询的SELECT列表内容作为基础来形成新的SET子句(紧接在WHERE子句之前)。

此代码适用于MySQL

UPDATE room r 

  INNER JOIN hotel h
  on h.hno = r.hno

SET
  r.type = 'King',
  r.price = r.price * 1.1

WHERE
  h.name = 'Scotty Hotel'
  and
  r.type = 'Double' ;

这段代码适用于MS SQL Server

UPDATE r

SET
  r.type = 'King',
  r.price = r.price * 1.1

FROM
  room r

  INNER JOIN hotel h
  on h.hno = r.hno

WHERE
  h.name = 'Scotty Hotel'
  and
  r.type = 'Double' ;

我给你点赞。请注意,这个更新语法 UPDATE a JOIN b SET ... 只适用于 MySQL。 - ypercubeᵀᴹ
@ypercube 很好的观点,谢谢。我已经添加了一个 MSSQL 版本,希望您能进行同行评审/编辑? - Sepster
@ypercube 我在寻找一种在 UPDATE 子句中引用表别名的方法,但我查看 MSDN 上的示例时,即使在 FROM 中使用别名,也仍然在那里使用了完整名称。感谢您为我澄清这一点。 - Sepster
我认为你原来的方法也可以,但我觉得这样更清晰。(还加了分号 :)) - ypercubeᵀᴹ

2

为什么这不起作用?

UPDATE ROOM A SET TYPE='King', A.PRICE=A.PRICE*1.1 
WHERE A.TYPE ='DOUBLE' AND 
A.HNO IN (SELECT HNO FROM HOTEL WHERE NAME='Scotty')

希望这能够正常工作。 当然,这假设酒店名称Scotty是唯一的。

HNO抱歉实际上是酒店的ID号码,而不是字符“scotty”。因此,我的假设是您需要连接表格以将“Scotty Hotel”放置为酒店名称? - user2182032

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接