在 INSERT INTO 語句中使用 TOP
我正在閱讀有關 T-SQL 中 TOP 關鍵字的教程。但我並不真正理解教程中給出的範例。
範例 1:
INSERT TOP n INTO table_name1 (Col1, Col2) SELECT Col3, Col4 FROM table_name2;
教程提到這裡的 TOP 並沒有真正實現任何東西,因為數據庫沒有順序的概念,我有點明白。
假設
n
從table_name2中選擇的行是完全隨機的記錄是否正確?範例 2:
本教程提供了另一個改進第一個語句的範例。
INSERT INTO table_name1 (Col1, Col2) SELECT TOP n Col3, Col4 FROM table_name2 Order By Col1;
這是令人困惑的部分。將 TOP 關鍵字放在 SELECT 語句中應該可以讓我們更好地控制通過 ORDER BY 子句選擇和插入的行。所以我假設 ORDER BY 子句是第二個範例中 SELECT 語句的一部分。但是Col1不是table_name2的一部分。
這讓我很困惑。感謝您的任何見解。
假設從 table_name2 中選擇的 n 行是完全隨機的記錄是否正確?
未指定順序時,通常會使用 的主鍵設計中的排序欄位和方向
table_name2
,但不保證。正如亞倫伯特蘭所說聚集索引是什麼並不重要。SQL Server 可能仍會基於多種因素基於其他一些索引返回訂單。在某些列上創建主鍵並不能保證沒有 order by 的選擇會突然返回總是按該列排序。大多數時候你會觀察到嗎?當然。但這不等於保證。我從來沒有在我的街道上看到過北極熊,但沒有北極熊力場可以阻止它的發生。– 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;
啊啊啊。這是可怕的編碼。這將按
Col1 ASC
table_name2 排序,即使您的SELECT
子句沒有從第二個表中顯式返回 Col1。它不是由Col3
第二張桌子Col1
或第一張桌子訂購的。MS 文件INSERT INTO
沒有列出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
我仍然建議按排序順序進行排序,如上所示。您不能為插入記錄的表設置別名(例如,這不是 SQL Server 現有版本的合法語法。Col4``table_name2``table_name1 AS t1 (t1.Col1, t1.Col2)
基於意見的推薦:避開你找到的教程網站。
如果這是書上所說的,那麼它充其量是誤導性的,
至少在 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 上排序
這不是名稱衝突
,order by 是 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