SQL 通过连接更新表?

Posted

技术标签:

【中文标题】SQL 通过连接更新表?【英文标题】:SQL update table via join? 【发布时间】:2013-04-01 12:10:03 【问题描述】:

我有以下数据库并希望更新room 表。表格room列出了单人房、双人房或特大床房型,价格为每间客房每晚的价格,酒店名称为酒店名称。

我需要做的是把所有双人房改成在斯科蒂酒店的特大床房,而且价格也提高了 10%。

我知道如何在单个表中更新价格和类型,但似乎在这里我需要加入 HNO 上的酒店和房间并因此更新。可能是嵌套查询?

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)
);

我有两个主要问题:

    是否可以对需要连接的表进行更新?

    我想通过视图列出来宾。我可以创建一个包含酒店名称和曾入住酒店的不同客人数量的视图吗?

【问题讨论】:

你在用什么RDBMS? RDBMS 代表关系数据库管理系统RDBMS is the basis for SQL,适用于所有现代数据库系统,如 MS SQL Server、IBM DB2、Oracle、mysql 等... 您在上面的代码中有多个错误,因此我无法快速构建 SQL Fiddle 来帮助您解决此问题。例如,create table Hotel 末尾的附加右括号 ) @Sepster 你看到了什么错误?除了在某些 DBMS 中不需要的 ;,我什么也没看到。 @ypercube 我最初并没有在遇到的第一个问题之外进行调试,但是是的,事实证明它只是缺少;。我必须承认我假设了 mySql。已编辑代码以反映 - 我添加了;,因为我相信虽然它们不是普遍需要的,但它们几乎被普遍接受? (如果不是这样,请重新编辑)。 【参考方案1】:

首先,最好进行选择以确保您的搜索/过滤条件正确:

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 子句的内容以形成新的 UPDATE 子句),将 WHERE 保留在原位,并使用 @987654329 的内容来自原始查询的@list 作为形成新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' ;

【讨论】:

+1 来自我。请注意,此更新 UPDATE a JOIN b SET ... 的语法仅适用于 MySQL。 @ypercube 好点,谢谢。我添加了一个 MSSQL 版本,我会感谢您的同行评审/编辑? @ypercube 我在 寻找 寻​​找在 UPDATE 子句中引用表别名的方法,但我在 MSDN 上查看的示例使用全名,即使在FROM 中使用别名。感谢您为我解决这个问题。 我认为它也可以像你一样工作,但我发现这样更清楚。 (还添加了; :)【参考方案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 sorry 实际上是酒店的 ID 号,而不是字符“scotty”。所以我的假设是您必须加入表格才能将“Scotty Hotel”作为酒店名称?

以上是关于SQL 通过连接更新表?的主要内容,如果未能解决你的问题,请参考以下文章

使用连接表的 AVG 进行 SQL 更新

无法通过带有 TableAdapter 的视图更新 SQL

如何加快 SQL 中的连接更新?我的陈述似乎无限期地运行

通过比较两个表来更新 SQL 查询

通过连接多个表来更新表

无法通过php更新sql表