在SQL Server中,UPDATE和DELETE语句是可以结合INNER/LEFT/RIGHT/FULL JOIN来使用的。
我们首先在数据库中新建两张表:
[T_A]
CREATE TABLE [dbo].[T_A]( [ID] [int] NOT NULL, [Name] [nvarchar](50) NULL, [Age] [int] NULL, CONSTRAINT [PK_T_A] PRIMARY KEY CLUSTERED ( [ID] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY]
[T_B]
CREATE TABLE [dbo].[T_B]( [ID] [int] NOT NULL, [Name] [nvarchar](50) NULL, [Age] [int] NULL, CONSTRAINT [PK_T_B] PRIMARY KEY CLUSTERED ( [ID] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY]
UPDATE与INNER/LEFT/RIGHT/FULL JOIN
UPDATE结合INNER JOIN:
TRUNCATE TABLE [T_A]; TRUNCATE TABLE [T_B]; INSERT INTO [T_A]([ID],[Name],[Age]) VALUES (1,N'Tome',10), (2,N'Jack',20), (3,N'Jim',30), (4,N'Mike',40), (5,N'Bob',50); INSERT INTO [T_B]([ID],[Name],[Age]) VALUES (1,N'Tome',100), (2,N'Jack',200), (3,N'Jim',300); UPDATE [T_A] SET Age=[T_B].Age FROM [T_A] INNER JOIN [T_B] ON [T_A].ID=[T_B].ID; SELECT * FROM [dbo].[T_A];
表[T_A]的结果如下所示:
其效果相当于通过下面INNER JOIN查询,先找出表[T_A]的数据记录,然后UPDATE这些找出的数据记录:
SELECT [T_A].*, [T_B].* FROM [T_A] INNER JOIN [T_B] ON [T_A].ID=[T_B].ID;
注意如果表[T_A]中的某行数据与表[T_B]中多行数据匹配上,这种情况下,表[T_A]的该行数据也只会被UPDATE一次,不过用表[T_B]中的哪一行匹配数据去UPDATE表[T_A]是不确定的。
UPDATE结合LEFT JOIN:
TRUNCATE TABLE [T_A]; TRUNCATE TABLE [T_B]; INSERT INTO [T_A]([ID],[Name],[Age]) VALUES (1,N'Tome',10), (2,N'Jack',20), (3,N'Jim',30), (4,N'Mike',40), (5,N'Bob',50); INSERT INTO [T_B]([ID],[Name],[Age]) VALUES (1,N'Tome',100), (2,N'Jack',200), (3,N'Jim',300); UPDATE [T_A] SET Age=[T_B].Age FROM [T_A] LEFT JOIN [T_B] ON [T_A].ID=[T_B].ID; SELECT * FROM [dbo].[T_A];
表[T_A]的结果如下所示:
其效果相当于通过下面LEFT JOIN查询,先找出表[T_A]的数据记录,然后UPDATE这些找出的数据记录:
SELECT [T_A].*, [T_B].* FROM [T_A] LEFT JOIN [T_B] ON [T_A].ID=[T_B].ID;
UPDATE结合RIGHT JOIN:
TRUNCATE TABLE [T_A]; TRUNCATE TABLE [T_B]; INSERT INTO [T_A]([ID],[Name],[Age]) VALUES (1,N'Tome',10), (2,N'Jack',20), (3,N'Jim',30), (4,N'Mike',40), (5,N'Bob',50); INSERT INTO [T_B]([ID],[Name],[Age]) VALUES (1,N'Tome',100), (2,N'Jack',200), (3,N'Jim',300), (4,N'Mike',400), (5,N'Bob',500), (6,N'Clark',600), (7,N'Sam',700); UPDATE [T_A] SET Age=[T_B].Age FROM [T_A] RIGHT JOIN [T_B] ON [T_A].ID=[T_B].ID; SELECT * FROM [dbo].[T_A];
表[T_A]的结果如下所示:
其效果相当于通过下面RIGHT JOIN查询,先找出表[T_A]的数据记录,然后UPDATE这些找出的数据记录:
SELECT [T_A].*, [T_B].* FROM [T_A] RIGHT JOIN [T_B] ON [T_A].ID=[T_B].ID;
UPDATE结合FULL JOIN:
TRUNCATE TABLE [T_A]; TRUNCATE TABLE [T_B]; INSERT INTO [T_A]([ID],[Name],[Age]) VALUES (1,N'Tome',10), (2,N'Jack',20), (3,N'Jim',30), (4,N'Mike',40), (5,N'Bob',50); INSERT INTO [T_B]([ID],[Name],[Age]) VALUES (1,N'Tome',100), (2,N'Jack',200), (3,N'Jim',300); UPDATE [T_A] SET Age=[T_B].Age FROM [T_A] FULL JOIN [T_B] ON [T_A].ID=[T_B].ID; SELECT * FROM [dbo].[T_A];
表[T_A]的结果如下所示:
其效果相当于通过下面FULL JOIN查询,先找出表[T_A]的数据记录,然后UPDATE这些找出的数据记录:
SELECT [T_A].*, [T_B].* FROM [T_A] FULL JOIN [T_B] ON [T_A].ID=[T_B].ID;
DELETE与INNER/LEFT/RIGHT/FULL JOIN
DELETE结合INNER JOIN:
TRUNCATE TABLE [T_A]; TRUNCATE TABLE [T_B]; INSERT INTO [T_A]([ID],[Name],[Age]) VALUES (1,N'Tome',10), (2,N'Jack',20), (3,N'Jim',30), (4,N'Mike',40), (5,N'Bob',50); INSERT INTO [T_B]([ID],[Name],[Age]) VALUES (1,N'Tome',100), (2,N'Jack',200), (3,N'Jim',300); DELETE [T_A] FROM [T_A] INNER JOIN [T_B] ON [T_A].ID=[T_B].ID; SELECT * FROM [dbo].[T_A];
表[T_A]的结果如下所示:
其效果相当于通过下面INNER JOIN查询,先找出表[T_A]的数据记录,然后DELETE这些找出的数据记录:
SELECT [T_A].* FROM [T_A] INNER JOIN [T_B] ON [T_A].ID=[T_B].ID;
DELETE结合LEFT JOIN:
TRUNCATE TABLE [T_A]; TRUNCATE TABLE [T_B]; INSERT INTO [T_A]([ID],[Name],[Age]) VALUES (1,N'Tome',10), (2,N'Jack',20), (3,N'Jim',30), (4,N'Mike',40), (5,N'Bob',50); INSERT INTO [T_B]([ID],[Name],[Age]) VALUES (1,N'Tome',100), (2,N'Jack',200), (3,N'Jim',300); DELETE [T_A] FROM [T_A] LEFT JOIN [T_B] ON [T_A].ID=[T_B].ID; SELECT * FROM [dbo].[T_A];
表[T_A]的结果如下所示:
其效果相当于通过下面LEFT JOIN查询,先找出表[T_A]的数据记录,然后DELETE这些找出的数据记录:
SELECT [T_A].* FROM [T_A] LEFT JOIN [T_B] ON [T_A].ID=[T_B].ID;
DELETE结合RIGHT JOIN:
TRUNCATE TABLE [T_A]; TRUNCATE TABLE [T_B]; INSERT INTO [T_A]([ID],[Name],[Age]) VALUES (1,N'Tome',10), (2,N'Jack',20), (3,N'Jim',30), (4,N'Mike',40), (5,N'Bob',50); INSERT INTO [T_B]([ID],[Name],[Age]) VALUES (1,N'Tome',100), (2,N'Jack',200), (3,N'Jim',300), (4,N'Mike',400), (5,N'Bob',500), (6,N'Clark',600), (7,N'Sam',700); DELETE [T_A] FROM [T_A] RIGHT JOIN [T_B] ON [T_A].ID=[T_B].ID; SELECT * FROM [dbo].[T_A];
表[T_A]的结果如下所示:
其效果相当于通过下面RIGHT JOIN查询,先找出表[T_A]的数据记录,然后DELETE这些找出的数据记录:
SELECT [T_A].* FROM [T_A] RIGHT JOIN [T_B] ON [T_A].ID=[T_B].ID;
DELETE结合FULL JOIN:
TRUNCATE TABLE [T_A]; TRUNCATE TABLE [T_B]; INSERT INTO [T_A]([ID],[Name],[Age]) VALUES (1,N'Tome',10), (2,N'Jack',20), (3,N'Jim',30), (4,N'Mike',40), (5,N'Bob',50); INSERT INTO [T_B]([ID],[Name],[Age]) VALUES (1,N'Tome',100), (2,N'Jack',200), (3,N'Jim',300); DELETE [T_A] FROM [T_A] FULL JOIN [T_B] ON [T_A].ID=[T_B].ID; SELECT * FROM [dbo].[T_A];
表[T_A]的结果如下所示:
其效果相当于通过下面FULL JOIN查询,先找出表[T_A]的数据记录,然后DELETE这些找出的数据记录:
SELECT [T_A].* FROM [T_A] FULL JOIN [T_B] ON [T_A].ID=[T_B].ID;
总结
举了这么多例子,其实我个人觉得UPDATE和DELETE语句与INNER JOIN结合使用才是最有用的,但是不管是什么JOIN,从上面的例子可以看出,其实都相当于是先用SELECT语句做表[T_A]的INNER/LEFT/RIGHT/FULL JOIN查询,然后UPDATE或DELETE表[T_A]中查询出的这些数据记录。