使用萬用字元選擇查詢中的所有列

考慮具有以下兩個表的資料庫。

員工表:

ID FName 引數 LName DEPTID
1 詹姆士 工匠 3
2 約翰 約翰遜 4

部門表:

ID 名稱
1 銷售
2 營銷
3 金融
4

簡單的選擇語句

*是用於選擇表中所有可用列的萬用字元

當用作顯式列名的替代時,它返回查詢正在選擇 FROM 的所有表中的所有列。此效果適用於查詢通過其 JOIN 子句訪問的所有表

請考慮以下查詢:

SELECT * FROM Employees

它將返回 Employees 表的所有行的所有欄位:

ID FName 引數 LName DEPTID
1 詹姆士 工匠 3
2 約翰 約翰遜 4

點符號

要從特定表中選擇所有值,可以使用點表示法將萬用字元應用於表。

請考慮以下查詢:

SELECT 
    Employees.*, 
    Departments.Name
FROM 
    Employees
JOIN 
    Departments 
    ON Departments.Id = Employees.DeptId

這將返回包含 Employee 表中所有欄位的資料集,然後只返回 Departments 表中的 Name 欄位:

ID FName 引數 LName DEPTID 名稱
1 詹姆士 工匠 3 金融
2 約翰 約翰遜 4

警告不使用

通常建議儘可能避免在生產程式碼中使用*,因為它可能會導致許多潛在問題,包括:

  1. 由於資料庫引擎讀取不需要的資料並將其傳輸到前端程式碼,因此 IO 過多,網路負載,記憶體使用等等。特別關注的是可能存在大欄位,例如用於儲存長音符或附加檔案的欄位。
  2. 如果資料庫需要將內部結果假離線到磁碟作為處理比 SELECT <columns> FROM <table> 更復雜的查詢的一部分,則會進一步超出 IO 負載。
  3. 如果某些不需要的列是:執行額外處理(和/或甚至更多 IO):
    • 支援它們的資料庫中的計算列
    • 在從檢視中進行選擇的情況下,查詢優化器可以以其他方式優化的表/檢視中的列
  4. 如果將列新增到表和檢視中,導致模糊列名稱,則可能會出現意外錯誤。例如 SELECT * FROM orders JOIN people ON people.id = orders.personid ORDER BY displayname - 如果將一個名為 displayname 的列列新增到 orders 表中以允許使用者為將來的引用提供有意義的名稱,那麼列名將在輸出中出現兩次,因此 ORDER BY 子句將是不明確的,這可能會導致錯誤(最近的 MS SQL Server 版本中的模糊列名稱,如果不是在此示例中,你的應用程式程式碼可能會開始顯示人名所在的訂單名稱,因為新列是返回的第一個名稱,依此類推。

什麼時候可以使用*,記住上面的警告?

雖然在生產程式碼中最好避免使用*,但在對資料庫進行手動查詢以進行調查或原型工作時,可以使用*作為簡寫。

有時候你的應用程式中的設計決定會使它不可避免(在這種情況下,如果可能的話,更喜歡 tablealias.*而不是*)。

當使用 EXISTS 時,例如 SELECT A.col1, A.Col2 FROM A WHERE EXISTS (SELECT * FROM B where A.ID = B.A_ID),我們不會從 B 返回任何資料。因此,連線是不必要的,並且引擎知道不返回 B 的值,因此使用*沒有效能損失。類似地,COUNT(*) 很好,因為它實際上也不會返回任何列,因此只需要讀取和處理那些用於過濾目的的列。