Sql server 返回顺序id的SQL函数

Sql server 返回顺序id的SQL函数,sql-server,Sql Server,考虑这个简单的插入 INSERT INTO Assignment (CustomerId,UserId) SELECT CustomerId,123 FROM Customers 这显然会将UserId=123分配给所有客户 我需要做的是按顺序将它们分配给3个userId,这样3个用户就可以平均获得三分之一的帐户 INSERT INTO Assignment (CustomerId,UserId) SELECT CustomerId,fnGetNextId() FROM Customers

考虑这个简单的插入

INSERT INTO Assignment (CustomerId,UserId)
SELECT CustomerId,123 FROM Customers
这显然会将UserId=123分配给所有客户

我需要做的是按顺序将它们分配给3个userId,这样3个用户就可以平均获得三分之一的帐户

INSERT INTO Assignment (CustomerId,UserId)
SELECT CustomerId,fnGetNextId() FROM Customers
我是否可以创建一个函数,从3个ID的列表中按顺序返回?即,每次调用该函数时,它都会返回列表中的下一个ID

谢谢

我可以创建一个函数从3个ID的列表中顺序返回吗


如果创建,则可以使用表达式指定增量数字。

这是一个奇怪的要求,但模数运算符%应该可以帮助您解决此问题,而无需函数、序列或更改数据库结构。这假设ID是整数。如果不是,您可以使用ROW_NUMBER或其他一些策略为每个客户获得不同的数值

显然,一旦您对代码感到满意,您就会用INSERT替换SELECT语句,但是在插入之前开发时始终选择是一种很好的做法

使用示例数据设置:

DECLARE @Users TABLE (ID int, [Name] varchar(50))
DECLARE @Customers TABLE (ID int, [Name] varchar(50))
DECLARE @Assignment TABLE (CustomerID int, UserID int)

INSERT INTO @Customers
VALUES
(1, 'Joe'),
(2, 'Jane'),
(3, 'Jon'),
(4, 'Jake'),
(5, 'Jerry'),
(6, 'Jesus')

INSERT INTO @Users 
VALUES
(1, 'Ted'),
(2, 'Ned'),
(3, 'Fred')
查询:

SELECT C.Name AS [CustomerName], U.Name AS [UserName]
FROM @Customers C
JOIN @Users U
    ON 
        CASE    WHEN C.ID % 3 = 0 THEN 1
                WHEN C.ID % 3 = 1 THEN 2
                WHEN C.ID % 3 = 2 THEN 3
        END = U.ID
您可以将THEN 1更改为您的第一个用户标识,然后将2更改为第二个用户标识,然后将3更改为第三个用户标识。如果您最终与另一个用户合并,并希望以4种方式拆分客户,那么您可以使用以下内容替换案例陈述:

        CASE    WHEN C.ID % 4 = 0 THEN 1
                WHEN C.ID % 4 = 1 THEN 2
                WHEN C.ID % 4 = 2 THEN 3
                WHEN C.ID % 4 = 3 THEN 4
        END = U.ID
输出:

CustomerName                                       UserName
-------------------------------------------------- --------------------------------------------------
Joe                                                Ned
Jane                                               Fred
Jon                                                Ted
Jake                                               Ned
Jerry                                              Fred
Jesus                                              Ted

(6 row(s) affected)
最后,您需要为实际插入选择ID,但我选择了名称,因此结果更容易理解。如果需要澄清,请告诉我。

这里有一种方法可以生成自动重新平衡视图的作业:

CREATE VIEW dbo.Assignment WITH SCHEMABINDING AS 
    WITH SeqUsers AS (
        SELECT UserID, ROW_NUMBER() OVER (ORDER BY UserID) - 1 AS _ord
        FROM dbo.Users
    ), SeqCustomers AS (
        SELECT CustomerID, ROW_NUMBER() OVER (ORDER BY CustomerID) - 1 AS _ord
        FROM dbo.Customers
    )
    -- INSERT Assignment(CustomerID, UserID)
    SELECT SeqCustomers.CustomerID, SeqUsers.UserID
    FROM SeqUsers 
    JOIN SeqCustomers ON SeqUsers._ord = SeqCustomers._ord % (SELECT COUNT(*) FROM SeqUsers)
;

如果您插入了一个新用户,这会改变分配,这可能是非常不受欢迎的,而且如果您必须加入,这也没有效率。您可以轻松地重新调整其包含的查询的用途,以便一次性插入已注释掉的插入。这里的关键技术是在行号上进行连接。

为自动递增的赋值添加标识列?-即使它们不完全是顺序的,它们也会被订购。哈哈@AlexK。是否可以添加新用户?如果是,会发生什么?工作分配是否应自动重新平衡,以便所有客户都能重新分配,还是现有工作分配保持不变?您将如何使用这些顺序值从其他数字列表中进行选择,就像我们在这个问题中所希望的那样?的下一个值在使用上受到很大限制。具体来说,它不能用在ON子句或子查询中。我误解了这个问题:我试图让它与序列一起工作,但我做不到。很高兴知道不是我。从技术上讲,它仍然可以工作,但前提是您的表ID恰好是完全连续的,没有删除的间隙,这不是很可能的情况。