T-SQLのTOPキーワードに関するチュートリアルを読んでいます。しかし、私はチュートリアルで与えられた例を本当に理解していません。
例1:
INSERT TOP n INTO table_name1 (Col1, Col2)
SELECT Col3, Col4 FROM table_name2;
このチュートリアルでは、データベースには順序の概念がないので、TOPは実際には何も達成しないと述べています。
そして、table_name2から選択されたn
行が完全にランダムなレコードであると想定することは正しいですか?
例2:
チュートリアルは、最初のステートメントを改善する別の例を示します。
INSERT INTO table_name1 (Col1, Col2)
SELECT TOP n Col3, Col4
FROM table_name2
Order By Col1;
これは混乱する部分です。 SELECTキーワード内にTOPキーワードを配置すると、ORDER BY句によってどの行が選択および挿入されるかをより適切に制御できるようになります。したがって、2番目の例では、ORDER BY句がSELECTステートメントの一部であると想定します。ただし、Col1はtable_name2の一部ではありません。
これは私の地獄を混乱させました。洞察をありがとう。
そして、table_name2から選択されたn行が完全にランダムなレコードであると想定することは正しいですか?
順序が指定されていない場合、通常は_table_name2
_の主キーの設計からのソートフィールドと方向が使用されますが、保証はされません。 Aaron Bertrandの発言
クラスタ化インデックスが何であるかは問題ではありません。 SQL Serverは、さまざまな要因に基づく他のインデックスに基づいて注文を返す場合があります。一部の列に主キーを作成しても、順序なしのselectがその列で常に順序付けられた突然の復帰を保証するわけではありません。ほとんどの場合それを観察しましたか?承知しました。しかし、それは保証と同じではありません。私は通りでホッキョクグマを見たことがありませんが、それが起こるのを妨げるホッキョクグマの力場はありません。 – Aaron Bertrand♦2011年9月14日20:41
PKのインデックス順で返したい場合でも、order句を追加しても問題はありません。
チュートリアルの例から
_INSERT INTO table_name1 (Col1, Col2)
SELECT TOP n Col3, Col4
FROM table_name2
Order By Col1;
_
ガァァァァ。それは恐ろしいコーディングです。 SELECT
句が2番目のテーブルから明示的にCol1を返していなくても、table_name2の_Col1 ASC
_によって順序付けされます。 2番目のテーブルの_Col3
_、つまり1番目のテーブルの_Col1
_によって順序付けされていません。 _INSERT INTO
_のMSドキュメント _ORDER BY
_句をリストしないでください -_ORDER BY
_は内部SELECT句の一部です。
挿入するテーブルと選択するテーブルを明示的に指定することをお勧めします。例えば。これは少しより良い例です。
_INSERT INTO
table_name1 (Col1, Col2)
SELECT TOP 3
t2.Col3
,t2.Col4
FROM
table_name2 AS t2
ORDER BY
t2.Col1 ASC, t2.Col3 ASC, t2.Col4 ASC
_
この変更後、_Col1
_の意味(またはその並べ替え順序)について混乱はありません。上記の例のように、Col1が_Col3
_のすべてのエントリに対して一意でない場合は、_Col4
_および_table_name2
_のソート順でスローすることをお勧めします。レコードが挿入されるテーブル(table_name1 AS t1 (t1.Col1, t1.Col2)
など)にエイリアスを設定することはできません。これは、SQL Serverの既存のバージョンでは有効な構文ではないためです。
意見に基づく推奨:見つけたチュートリアルWebサイトは避けてください。
本が言うことであるなら、それはせいぜい誤解を招くだけです
少なくともMSSQL 2012
挿入(col1、col2)はインデックスベースです
選択の最初の項目がcol1に入ります
データタイプは同じである必要があります
選択はそれ自体で成り立っており、挿入の列名を認識していません
Example1は、一部のデータが必要な場合にのみ有効であり、気にしない
テストにはデータが必要です
これは、table_name2にcol1がある場合にのみ有効です。
その場合、多くの人々がtable_name1.Col1を意味すると想定するので、それは恐ろしい例です。
INSERT INTO table_name1 (Col1, Col2)
SELECT TOP n Col3, Col4
FROM table_name2
Order By Col1;
より良い例は
INSERT INTO table_name1 (Col1, Col2)
SELECT TOP (n) Col3, Col4
FROM table_name2
Order By Col3;
Col1がクラスター化されたインデックスであり、すべて挿入してもcol3でソートする必要があるとしましょう
これは名前の競合ではありません
その順序はtable_name2です
INSERT INTO table_name1 (Col3, Col4)
SELECT TOP (n) Col3, Col4
FROM table_name2
Order By Col3;
これは、並べ替えなしでtopを使用する可能性がある状況ですが、削除です
トランザクションログがいっぱいにならないようにするため
select 1
while (@@rowcount > 0)
begin
delete top(10000) from table1
end
トランザクションログがいっぱいになる挿入
select 1
while (@@rowcount > 0)
begin
INSERT INTO table_name1 (Col3, Col4)
SELECT TOP (n) T2.Col3, T2.Col4
FROM table_name2 T2
LEFT JOIN table_name1 T1
on T1.Col3 = T2.Col3
WHERE T1.Col3 is null
Order By Col3;
end