4

tempTable複数の番号付き列 ( rep1rep2、...)を持つ典型的な正規化されていないテーブル ( ) がありました。そこで、正規化されていないデータを正規化されたテーブル ( myTable)に挿入するスクリプトを作成しました。

insert into myTable
select idRep,rep FROM
(
    select idRep, ISNULL(rep1,'') as rep FROM tempTable
    union
    select idRep, ISNULL(rep2,'') as rep FROM tempTable
    union
    select idRep, ISNULL(rep3,'') as rep FROM tempTable
    union
    select idRep, ISNULL(rep4,'') as rep FROM tempTable
    union
    select idRep, ISNULL(rep5,'') as rep FROM tempTable
) as t

注: テーブルmyTableには、自動インクリメントIDENTITY列も含まれていPRIMARY KEYます。

私のシナリオでは、rep1、rep2、rep3、rep4、rep5 の順序が重要です。奇妙なことに、スクリプトを実行すると、自動生成された ID '1000' が 'rep3' の値を持ち、ID '1001' が 'rep1' の値を持っているなど、データが正しい順序で挿入されませんでした。

何故ですか?スクリプトはどのように実行されましたか?

4

3 に答える 3

9

UNION を使用するときに期待どおりの順序にならないのは、ユニオンが一意性を課そうとするためです。そのため、これらのすべての行をまとめて処理し、エンジンにとって最も便利な順序でそれらを取り出します。

Paradoが提案したようにUNION ALL(一意性を課そうとしない)に切り替えると、処理は行われず、ほとんどの場合、入れた順序でテーブルに入れられます。ただし、これは保証されたものではなく、他のプロセス (特に何らかの方法で tempTable に触れるプロセス) で発生する特定の非常に異常な状況が影響を与える可能性があります。

Kashが示唆するようにオーダーバイを使用すると、IDの順序が保証されますが(これは問題になる可能性があります)、技術的には行が挿入される順序ではありません(実際にはほとんど問題になりません)。

MSDNには、これに関するいくつかの優れた要約があります。

それで、それは理由を処理します。実際に必要なものを取得する方法については、order by 句で使用する列を追加するという Kash の提案を使用しますが、UNION の代わりに UNION ALL を使用します。UNION を使用することは、プロセッサ サイクルを占有し、クエリ プランをより複雑にする暗黙の「個別」要件を追加するようなものです。

于 2012-09-10T21:48:30.147 に答える
4

あなたの外側Selectには順序がないため、INSERT は見た目のように順序付けられていません。

SQL Server にはいくつかの順序保証があり、ORDER BY を使用した SELECT の INSERT は、引用されているように ID 値の計算を保証します。

SELECT と ORDER BY を使用して行にデータを入力する INSERT クエリでは、ID 値の計算方法は保証されますが、行が挿入される順序は保証されません。

SQL を変更して順序付けます。

insert into myTable
select idRep,rep FROM
(
    select idRep, ISNULL(rep1,'') as rep, 1 as Grp FROM tempTable
    union
    select idRep, ISNULL(rep2,'') as rep, 2 as Grp FROM tempTable
    union
    select idRep, ISNULL(rep3,'') as rep, 3 as Grp FROM tempTable
    union
    select idRep, ISNULL(rep4,'') as rep, 4 as Grp FROM tempTable
    union
    select idRep, ISNULL(rep5,'') as rep, 5 as Grp FROM tempTable
) as t ORDER BY Grp
于 2012-09-10T21:29:00.193 に答える
2

で試してくださいunion all。データはソートされません。

insert into myTable
select idRep,rep FROM
(
    select idRep, ISNULL(rep1,'') as rep FROM tempTable
    union all
    select idRep, ISNULL(rep2,'') as rep FROM tempTable
    union all
    select idRep, ISNULL(rep3,'') as rep FROM tempTable
    union all
    select idRep, ISNULL(rep4,'') as rep FROM tempTable
    union all
    select idRep, ISNULL(rep5,'') as rep FROM tempTable
) as t
于 2012-09-10T21:25:22.570 に答える