次のような3つのテーブルを持つデータベースがあります。
Orders テーブルには、次のようなデータがあります。
OrderID OperatorID GroupID OrderDesc Status Cash ...
--------------------------------------------------------------------------
1 1 1 small order 1 100
2 1 1 another order 2 0
3 1 2 xxxxxxxxxxx 2 1000
5 2 2 yyyyyyyyyyy 2 150
9 5 1 xxxxxxxxxxx 1 0
10 NULL 2 xxxxxxxxxxx 1 10
11 NULL 3 xxxxxxxxxxx 1 120
演算子テーブル:
OperatorID Name GroupID Active
---------------------------------------
1 John 1 1
2 Kate 1 1
4 Jack 2 1
5 Will 1 0
6 Sam 3 1
グループテーブル:
GroupID Name
---------------
1 G1
2 G2
3 X1
ご覧のとおり、ジョンには 3 つの注文があり、ケイト 1、ウィル 1、ジャック、サムにはありません。
ここで、いくつかの条件に基づいてオペレーターを注文に割り当てたいと思います。
- 注文には現金が必要です > 0
- 注文には status=1 が必要です
- オーダーはグループ 1 または 2 に属している必要があります
- オペレーターはアクティブでなければなりません (アクティブ = 1)
- オペレータはグループ 1 または 2 に属している必要があります
これは私が得たい結果です:
OrderID OperatorID GroupID OrderDesc Status Cash ...
--------------------------------------------------------------------------
1 1 1 small order 1 100 < change
2 1 1 another order 2 0
3 2 2 xxxxxxxxxxx 2 1000 < change
5 4 2 yyyyyyyyyyy 2 150 < change
9 5 1 xxxxxxxxxxx 1 0
10 4 2 xxxxxxxxxxx 1 10 < change
11 NULL 3 xxxxxxxxxxx 1 120
注文をシャッフルして operatorID を更新し、このスクリプトを呼び出すたびに割り当て担当者の operatorID がランダムに取得されるようにしたいと思いますが、すべてのオペレーターは同じ数または注文を持ちます (注文が 7 つある場合、1 人が 3 つになり残りが残ります)。 2)。
を使用NTILE
してオーダーをグループに分散できますが、operatorID をそのグループに割り当てる必要があります。
私はこのようなことをする必要があると思います:
SELECT NTILE(2) OVER( order by orderID desc) as newID,*
FROM
orders(NOLOCK)
これにより、等しい部分にグループ化された注文テーブルが得られます。私が知る必要があるのは、演算子テーブルの長さです(NTILEにパラメーターとして追加するため)。その後、結果を演算子と結合できます(を使用row_number()
)
より良い解決策はありますか?
もう一度質問:結果セットをグループに均等に分割し、別のテーブル データを使用してそのレコード セットを更新するにはどうすればよいですか?
編集: これはこれまでの私のコードです: http://sqlfiddle.com/#!3/39849/25
EDIT 2 質問を更新し、条件を追加しました。
いくつかの条件に基づいて、オーダーにオペレーターを割り当てたいと考えています。
- 注文には現金が必要です > 0
- 注文には status=1 が必要です
- オーダーはグループ 1 または 2 に属している必要があります
- オペレーターはアクティブでなければなりません (アクティブ = 1)
- オペレータはグループ 1 または 2 に属している必要があります
このクエリをストアド プロシージャとして作成しています。
したがって、最初のステップは、新しい割り当てを含むデータを一時テーブルに生成し、2 番目のステップで最終承認を行った後、その一時テーブルに基づいてメイン テーブルを更新することです。
さらに 2 つの質問があります。
最初にすべての注文と条件を満たすすべてのオペレーターを一時テーブルに選択してからシャッフルを行うか、それとも 1 つの大きなクエリですべてを行う方がよいでしょうか?
配列またはグループをパラメーターとしてプロシージャーに渡したいと思います。配列をストアド プロシージャに渡すのに最適なオプションはどれですか (SQL Server 2005)。
これは何度も尋ねられたことは知っていますが、カンマ区切りの文字列をテーブルに分割する別の関数を作成する方がよいかどうかを知りたいです ( http://www.sommarskog.se/arrays-in-sql-2005.html ) または、すべてを 1 つの大きなファット プロシージャ内に配置しますか? :)
最終回答: http://sqlfiddle.com/#!3/afb48/2で入手可能
SELECT o.*, op.operatorName AS NewOperator, op.operatorID AS NewOperatorId
FROM (SELECT o.*, (ROW_NUMBER() over (ORDER BY newid()) % numoperators) + 1 AS randseqnum
FROM Orders o CROSS JOIN
(SELECT COUNT(*) AS numoperators FROM operators WHERE operators.active=1) op
WHERE o.cash>0 and o.status in (1,3)
) o JOIN
(SELECT op.*, ROW_NUMBER() over (ORDER BY newid()) AS seqnum
FROM Operators op WHERE op.active=1
) op
ON o.randseqnum = op.seqnum ORDER BY o.orderID
ゴードンのリノフの回答に基づく回答。ありがとう!