SQL Server:根据条件替代分配行

时间:2015-11-20 16:02:47

标签: sql sql-server

我正在创建一个工作流程电子表格,我想根据团队成员之间的位置平均分配列表。

即。 在2个状态中分配10行,细分如下:

弗吉尼亚州的7行

犹他州有3排

我想将每个州的行分配给该州的团队成员。

因此,如果Jane和John是犹他州的团队成员,而Jack和Jill是弗吉尼亚州的团队成员,那么就会这样分配:

Row 1  || AcctNo || City || Virginia || Jill

Row 2  || AcctNo || City || Utah     || Jane 

Row 3  || AcctNo || City || Utah     || John

Row 4  || AcctNo || City || Virginia || Jack

Row 5  || AcctNo || City || Utah     || Jane

Row 6  || AcctNo || City || Virginia || Jill

Row 7  || AcctNo || City || Virginia || Jack

Row 8  || AcctNo || City || Virginia || Jill

Row 9  || AcctNo || City || Virginia || Jack

Row 10 || AcctNo || City || Virginia || Jill

关于如何做到这一点的任何想法?谢谢!

编辑:

@BaconBits实际上这就是现在的数据:

enter image description here

我想分配行 国家=弗吉尼亚州然后'吉尔'或者'杰克' (交变)      当State = Utah然后' Jane'或者' John' (交变)

所以它看起来像这样:

enter image description here

编辑2:

我的查询如下:

enter image description here

1 个答案:

答案 0 :(得分:1)

这样做的一般想法是遍历帐户表,按州排序(或者将您的人员加入到表中)。执行此操作时,请对people表使用索引/游标并相应地进行分配。

使用索引,您可以跟踪分配给每个约会/帐户的人员,并在您不再有人员时将其重置为第一个人。

我使用临时表(实际上是table variables)为人们提供了一个容易运行的解决方案来解决这个问题。

declare @tempTablePeople TABLE 
( 
    [name] varchar(50), 
    [state] varchar(50), 
    [order] int
)
INSERT INTO @tempTablePeople 
VALUES
('Jack', 'Virginia', 1),
('Jill', 'Virginia', 2),
('Ron', 'Florida', 1),
('Bob', 'Florida', 2),
('Scott', 'Florida', 3);

declare @tempTableStateAccts TABLE 
( 
    [AcctNo] int,
    [state] varchar(50)
)
INSERT INTO @tempTableStateAccts 
VALUES
(22234, 'Virginia'),
(32432, 'Virginia'),
(02342, 'Florida'),
(43423, 'Virginia'),
(69449, 'Virginia'),
(33233, 'Florida'),
(52342, 'Florida'),
(33342, 'Florida'),
(77742, 'Florida'),
(69429, 'Virginia')



declare @tempTableStateAcctsPeople TABLE 
(
    [AcctNo] int,
    [state] varchar(50),
    [name] varchar(50)
)


DECLARE @currentAcct int;
DECLARE @currentState varchar(50);
DECLARE @lastState varchar(50);
DECLARE @currentNameIndex int;
DECLARE @currentName varchar(50);

查询的内容在这里,您使用索引循环遍历状态帐户表的行以跟踪。请注意,您需要按州排序才能获得所需的结果(否则您的索引会提前重置)。

SET @currentNameIndex = 1;
WHILE EXISTS ( SELECT * FROM @tempTableStateAccts)
BEGIN 
    -- Get current variables for insert from current row : MUST ORDER BY STATE if you want person order to not skip anyone at the start
    SELECT @currentAcct = AcctNo, @currentState = [state] FROM @tempTableStateAccts ORDER BY [state]
    -- Reset Index if on a new state
    IF @lastState IS NULL OR @lastState != @currentState
        SET @currentNameIndex = 1
    SET @lastState = @currentState
    -- If no current name then reset index to 1
    SET @currentName = ISNULL
                        ( 
                                (SELECT name FROM @tempTablePeople WHERE [state] = @currentState AND [order] = @currentNameIndex), 
                                (SELECT name FROM @tempTablePeople WHERE [state] = @currentState AND [order] = 1)
                        )
    SET @currentNameIndex = ISNULL
                        ( 
                                (SELECT @currentNameIndex FROM @tempTablePeople WHERE [state] = @currentState AND [order] = @currentNameIndex), 
                                1
                        )

    -- Get current person for this state based on index
    SELECT @currentName = name FROM @tempTablePeople WHERE [state] = @currentState AND [order] = @currentNameIndex

    INSERT INTO @tempTableStateAcctsPeople
    VALUES
    (
        @currentAcct, 
        @currentState,
        @currentName
    )
    SET @currentNameIndex = @currentNameIndex + 1
    DELETE FROM @tempTableStateAccts WHERE AcctNo = @currentAcct
END
-- View final data
SELECT * FROM @tempTableStateAcctsPeople

您可以按顺序粘贴SQL脚本的两个部分,然后运行它以查看结果。

AcctNo  state       name
32432   Virginia    Jack
69429   Virginia    Jill
22234   Virginia    Jack
69449   Virginia    Jill
43423   Virginia    Jack
77742   Florida     Ron
33342   Florida     Bob
52342   Florida     Scott
33233   Florida     Ron
2342    Florida     Bob