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

时间:2013-04-03 16:27:03

标签: sql-server sql-server-2008 tsql

我有2张桌子,一张包含人,另一张包含优惠券,我需要为每个人分配一张优惠券,并使用其分配给的人的身份更新优惠券表。由于没有用于连接表的公共密钥,因此我无法使用递归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')

2 个答案:

答案 0 :(得分:4)

这使用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;

答案 1 :(得分:3)

假设您的数据按照您希望的顺序排列

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

DECLARE @Vouchers TABLE (Voucher CHAR(5), 
                       Assigned INT)

INSERT INTO @Vouchers (Voucher)
    SELECT Voucher
    FROM
        (
        INSERT INTO @Persons (FirstName,LastName,Voucher)
        OUTPUT INSERTED.Voucher
        VALUES ('Rob','Smith', 'FEWPN'), ('Alan','Brown', 'FEWPN'), ('John','Plant', 'NGLCE'), ('Mike','Black', 'WEKFE'),('Steve','Green', 'POIAP')
        ) X   

SELECT * FROM @Persons P
SELECT * FROM @Vouchers V