7

次のような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. 最初にすべての注文と条件を満たすすべてのオペレーターを一時テーブルに選択してからシャッフルを行うか、それとも 1 つの大きなクエリですべてを行う方がよいでしょうか?

  2. 配列またはグループをパラメーターとしてプロシージャーに渡したいと思います。配列をストアド プロシージャに渡すのに最適なオプションはどれですか (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

ゴードンのリノフの回答に基づく回答。ありがとう!

4

2 に答える 2

0

申し訳ありませんが、レコードセットを数えることから逃れることはできないと思います...

DECLARE @myCount int
SELECT @myCount = Count(*) FROM Operators

SELECT
  a.OrderID, a.description, b.operatorName
FROM
  (
    SELECT NTILE(@myCount) OVER( ORDER BY NEWID()) AS newID, orderID, description
    FROM orders(NOLOCK)
  ) a
  INNER JOIN
  (
    SELECT NTILE(@myCount) OVER( ORDER BY NEWID()) AS newID, OperatorName, OperatorID
    FROM Operators
  ) b
  ON a.NewID = b.NewID
ORDER BY
   a.OrderID
于 2012-08-21T17:46:33.353 に答える