我正在使用MS SQL Server Management Studio。我有桌子-
+--------+----------+ | Num_ID | Alpha_ID | +--------+----------+ | 1 | A | | 1 | B | | 1 | C | | 2 | B | | 2 | C | | 3 | A | | 4 | C | | 5 | A | | 5 | B | +--------+----------+
我想从该表创建另一个包含2列的表,以便column_1在Num_ID中提供唯一值(即1,2,3,4等),而column_2在Alpha_ID中提供唯一值(A,B,C等) 。
但是,如果已经出现一个字母,则不应再次出现。所以输出将是这样的-
Col_1 Col_2 ================ 1 - A ---------------- 2 - B ---------------- 3 - NULL (as A has been chosen by 1, it cannot occur next to 3) ---------------- 4 - C ---------------- 5 - NULL (both 5 A and 5 B cannot be chosen as A and B were picked up by 1 and 2) ----------------
希望这是有道理的。我想澄清一下,输入表中的ID不是我所显示的数字,但是Num_ID和Alpha_ID都是复杂的字符串。为了这个问题,我已经将它们简化为1,2,3,…和A,B,C ....
我不认为没有光标就无法做到这一点。我在示例数据中添加了几行,以测试其在其他情况下的工作方式。
逻辑很简单。首先,获取的所有不同值的列表Num_ID。然后遍历它们,并在每次迭代中向目标表添加一行。为了确定Alpha_ID要添加的值,我将使用EXCEPT运算符,该运算符从源表中获取Alpha_ID当前电流的所有可用值,并Num_ID从中删除之前已使用的所有值。
Num_ID
Alpha_ID
EXCEPT
可以在INSERT不使用显式变量的情况下编写它@CurrAlphaID,但是使用变量看起来会更干净一些。
INSERT
@CurrAlphaID
这是SQL Fiddle。
DECLARE @TSrc TABLE (Num_ID varchar(10), Alpha_ID varchar(10)); INSERT INTO @TSrc (Num_ID, Alpha_ID) VALUES ('1', 'A'), ('1', 'B'), ('1', 'C'), ('2', 'B'), ('2', 'C'), ('3', 'A'), ('3', 'C'), ('4', 'A'), ('4', 'C'), ('5', 'A'), ('5', 'B'), ('5', 'C'), ('6', 'D'), ('6', 'E'); DECLARE @TDst TABLE (Num_ID varchar(10), Alpha_ID varchar(10)); DECLARE @CurrNumID varchar(10); DECLARE @CurrAlphaID varchar(10); DECLARE @iFS int; DECLARE @VarCursor CURSOR; SET @VarCursor = CURSOR FAST_FORWARD FOR SELECT DISTINCT Num_ID FROM @TSrc ORDER BY Num_ID; OPEN @VarCursor; FETCH NEXT FROM @VarCursor INTO @CurrNumID; SET @iFS = @@FETCH_STATUS; WHILE @iFS = 0 BEGIN SET @CurrAlphaID = ( SELECT TOP(1) Diff.Alpha_ID FROM ( SELECT Src.Alpha_ID FROM @TSrc AS Src WHERE Src.Num_ID = @CurrNumID EXCEPT SELECT Dst.Alpha_ID FROM @TDst AS Dst ) AS Diff ORDER BY Diff.Alpha_ID ); INSERT INTO @TDst (Num_ID, Alpha_ID) VALUES (@CurrNumID, @CurrAlphaID); FETCH NEXT FROM @VarCursor INTO @CurrNumID; SET @iFS = @@FETCH_STATUS; END; CLOSE @VarCursor; DEALLOCATE @VarCursor; SELECT * FROM @TDst;
结果
Num_ID Alpha_ID 1 A 2 B 3 C 4 NULL 5 NULL 6 D
在(Num_ID, Alpha_ID)源表上建立索引会有所帮助。在(Alpha_ID)目标表上建立索引也将有所帮助。
(Num_ID, Alpha_ID)
(Alpha_ID)