Sql-Server

在 INSERT INTO 語句中使用 TOP

  • July 4, 2016

我正在閱讀有關 T-SQL 中 TOP 關鍵字的教程。但我並不真正理解教程中給出的範例。

範例 1:

INSERT TOP n INTO table_name1 (Col1, Col2)
SELECT Col3, Col4 FROM table_name2;

教程提到這裡的 TOP 並沒有真正實現任何東西,因為數據庫沒有順序的概念,我有點明白。

假設ntable_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 ASCtable_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

引用自:https://dba.stackexchange.com/questions/142804