如何在没有连接且不使用循环的情况下更新 2 个表

Rob*_*w84 1 t-sql sql-server sql-server-2008

我有 2 个表,一个包含人,一个包含凭证,我需要为每个人分配一个凭证,并使用分配给它的人的 ID 更新凭证表。由于没有用于连接表的通用键,我不能使用递归 CTE,而且我总是尽量避免使用循环,但我想不出任何其他方式。

有没有办法不使用循环?最好在一个语句中。

这将给出表的示例(我使用的是 SQL Server 2008 R2)

CREATE TABLE Persons (ID INT IDENTITY(1,1), 
                      FirstName VARCHAR(30), 
                      LastName  VARCHAR(50),      
                      Voucher CHAR(5))

CREATE TABLE Vouchers (Voucher CHAR(5), 
                       Assigned INT)

INSERT INTO Persons (FirstName,LastName) VALUES ('Rob','Smith')
INSERT INTO Persons (FirstName,LastName) VALUES ('Alan','Brown')
INSERT INTO Persons (FirstName,LastName) VALUES ('John','Plant')
INSERT INTO Persons (FirstName,LastName) VALUES ('Mike','Black')
INSERT INTO Persons (FirstName,LastName) VALUES ('Steve','Green')

INSERT INTO Vouchers (Voucher) VALUES ('FEWPN')
INSERT INTO Vouchers (Voucher) VALUES ('ROPIW')
INSERT INTO Vouchers (Voucher) VALUES ('NGLCE')
INSERT INTO Vouchers (Voucher) VALUES ('WEKFE')
INSERT INTO Vouchers (Voucher) VALUES ('POIAP')
Run Code Online (Sandbox Code Playgroud)

Aar*_*and 5

这使用 CTE(不是递归的)并假设您不关心将哪个凭证分配给哪个人。每个人只有一张rn,每张代金券也是如此。

;WITH x AS 
(
  SELECT ID, Voucher, rn = ROW_NUMBER() OVER (ORDER BY ID) FROM dbo.Persons
),
y AS 
(
  SELECT Voucher, rn = ROW_NUMBER() OVER (ORDER BY Voucher) FROM dbo.Vouchers
)
UPDATE x SET Voucher = y.Voucher
  FROM x INNER JOIN y
  ON x.rn = y.rn;

UPDATE v SET Assigned = p.ID
  FROM dbo.Vouchers AS v
  INNER JOIN dbo.Persons AS p
  ON v.Voucher = p.Voucher;
Run Code Online (Sandbox Code Playgroud)