SQL函数返回顺序ID

时间:2017-07-07 15:37:26

标签: sql-server

考虑这个简单的INSERT

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的列表中按顺序返回的函数吗?,即每次调用该函数时它都返回列表中的下一个函数?

由于

3 个答案:

答案 0 :(得分:0)

  

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

如果您创建SEQUENCE,则可以使用NEXT VALUE FOR (Transact-SQL)表达式分配增量数字。

答案 1 :(得分:0)

这是一个奇怪的要求,但模数运算符($time1 = '10:50:00'; $time1 = '24:00:15'; )可以帮助您而不需要函数,序列或更改数据库结构。这假设ID是整数。如果不是,您可以使用%或其他一些策略为每位客户获取不同的数字值。

显然,一旦您对代码感到满意,就会用ROW_NUMBER替换SELECT语句,但最好在插入之前选择开发时选择。

使用示例数据设置:

INSERT

QUERY:

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 更改为您的第一个UserID,THEN 1使用第二个UserID,将THEN 2更改为第三个UserID。如果你最终得到了另一个用户,并希望以4种方式拆分客户,你可以用以下内容替换THEN 3语句:

CASE

输出:

        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

最后,您需要选择实际插入的ID,但我选择了名称,以便更容易理解结果。如果需要澄清,请告诉我。

答案 2 :(得分:0)

以下是将Assignment生成为自动重新平衡视图的一种方法:

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)
;

如果您插入新用户,这会改变分配,这可能是非常不受欢迎的,如果您不得不JOIN,那么它也无效。您可以轻松地重新调整其包含的查询以进行一次性插入(注释掉的INSERT)。关键技术是加入ROW_NUMBER() s。