2017-07-07 94 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()