sql >> データベース >  >> RDS >> Sqlserver

TSQL は、結果セットをグループに均等に分割して更新します

    更新クエリと選択クエリのどちらが本当に必要なのかわかりませんでした。次のクエリは、条件に従って、注文ごとに新しい演算子を返します:

    /*
    with orders as (select 1 as orderId, 'order1' as orderDesc, 1 as OperatorId),
         operators as (select 1 as operatorID, 'John' as name)
     */
    select o.*, op.name 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) op
         ) o join
         (select op.*, ROW_NUMBER() over (order by newid()) as seqnum
          from Operators op
         ) op
         on o.randseqnum = op.seqnum order by orderid 
    

    基本的に、結合の行に新しい ID を割り当てました。 order テーブルは、ランダムに割り当てられた 1 からオペレーターの数までの値を取得します。これは、オペレーターのシーケンス番号に結合されます。

    更新する必要がある場合は、次のようにすることができます:

    with toupdate as (<above query>)
    update orders
        set operatorid = newoperatorid
        from toupdate
        where toupdate.orderid = orders.orderid
    

    2 つの質問:

    最初に条件に一致するすべての注文とすべてのオペレーターを一時テーブルに選択してからシャッフルを実行するか、それとも 1 つの大きなクエリですべてを実行する方がよいでしょうか?

    一時テーブルのユーザーは、アプリケーションのパフォーマンスと要件の問題です。データが急速に更新されている場合、はい、一時テーブルを使用することは大きなメリットです。同じデータに対してランダム化を何度も実行している場合、特にテーブルが大きすぎてメモリに収まらない場合は、有利になる可能性があります。それ以外の場合、最も内側のサブクエリ内に条件を配置すると仮定すると、1 回の実行でパフォーマンスが大幅に向上する可能性は低くなります。ただし、パフォーマンスが問題になる場合は、2 つのアプローチをテストできます。

    配列またはグループをパラメータとしてプロシージャに渡したいです。配列をストアド プロシージャに渡すのに最適なオプションはどれですか (SQL Server 2005)。

    うーん、テーブル値パラメーターを持つ 2008 に切り替えます。 Erland Sommarskog によるこの件に関する非常に参考になる記事を次に示します。 www.sommarskog.se/arrays-in-sql-2005.html .



    1. データベースに接続するために付与されたロールを削除できません

    2. 順序付けられていない方法で文字列を比較するOracle関数

    3. T-SQLで年ごとにグループ化する方法

    4. PDO+MySQLおよび壊れたUTF-8エンコーディング