使用萬用字元選擇查詢中的所有列
考慮具有以下兩個表的資料庫。
員工表:
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 | 它 |
警告不使用
通常建議儘可能避免在生產程式碼中使用*
,因為它可能會導致許多潛在問題,包括:
- 由於資料庫引擎讀取不需要的資料並將其傳輸到前端程式碼,因此 IO 過多,網路負載,記憶體使用等等。特別關注的是可能存在大欄位,例如用於儲存長音符或附加檔案的欄位。
- 如果資料庫需要將內部結果假離線到磁碟作為處理比
SELECT <columns> FROM <table>
更復雜的查詢的一部分,則會進一步超出 IO 負載。 - 如果某些不需要的列是:執行額外處理(和/或甚至更多 IO):
- 支援它們的資料庫中的計算列
- 在從檢視中進行選擇的情況下,查詢優化器可以以其他方式優化的表/檢視中的列
- 如果將列新增到表和檢視中,導致模糊列名稱,則可能會出現意外錯誤。例如
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(*)
很好,因為它實際上也不會返回任何列,因此只需要讀取和處理那些用於過濾目的的列。