小编典典

用另一个表中的唯一值创建一个表

sql

我正在使用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
....


阅读 153

收藏
2021-04-28

共1个答案

小编典典

我不认为没有光标就无法做到这一点。我在示例数据中添加了几行,以测试其在其他情况下的工作方式。

逻辑很简单。首先,获取的所有不同值的列表Num_ID。然后遍历它们,并在每次迭代中向目标表添加一行。为了确定Alpha_ID要添加的值,我将使用EXCEPT运算符,该运算符从源表中获取Alpha_ID当前电流的所有可用值,并Num_ID从中删除之前已使用的所有值。

可以在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)目标表上建立索引也将有所帮助。

2021-04-28