1

我有 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')
4

2 回答 2

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;
于 2013-04-03T16:35:22.217 回答
4

假设您的数据按您想要的顺序排列

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
于 2013-04-03T16:36:19.787 回答