2017-07-07 51 views
0

考虑一个简单的INSERTSQL函数返回顺序编号的

INSERT INTO Assignment (CustomerId,UserId) 
SELECT CustomerId,123 FROM Customers 

这显然会指定用户ID = 123给所有客户。

我需要做的是将它们依次分配给3个userId,因此3个用户平均获得三分之一的帐户。

INSERT INTO Assignment (CustomerId,UserId) 
SELECT CustomerId,fnGetNextId() FROM Customers 

我能创建一个函数来从3号的?即每次列表顺序返回调用该函数返回列表中的下一个?

感谢

+3

添加一个标识列到自动增量自动分配的分配?即使他们最终没有完全顺序,他们也会被订购。 –

+1

哈哈@AlexK。 “automagically” –

+0

是否可以添加新用户?如果是这样,会发生什么?作业是否应该自动重新平衡,以便所有的顾客再次平等分工,或者现有的作业保持不变? –

回答

0

我能创建一个函数来如果创建SEQUENCE从3号的?

列表顺序返回,那么你就可以用NEXT VALUE FOR (Transact-SQL)表达分配增量编号。

+0

如何使用这些顺序值从其他数字列表中进行选择,就像我们在这个问题中想要的一样? “下一个价值”在使用上受到严格限制。具体而言,它不能用于'ON'子句或子查询。 –

+0

它不会。我误解了这个问题:) –

+0

我试图让它与一个序列工作,我不能。很高兴知道这不是我。 (从技术上讲,它仍然可以工作,但前提是你的表ID恰好是完全顺序的,并且没有删除的空白,这不是一个很可能的情况。) –

0

这是一个奇怪的要求,但模运算符(%)应该帮助您,而不需要函数,序列或更改数据库结构。这假定这些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') 

QUERY:

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到任何你的第一个用户名是THEN 2与第二用户名,并THEN 3与第三用户名。如果你最终与其他用户和要拆分的客户4种方式,你会做有以下替换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 

OUTPUT:

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

(6 row(s) affected) 

最后,你将要选择实际插入的ID,但是我选择了名称,以便更容易理解结果。请让我知道这是否需要澄清。

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