使用通配符选择查询中的所有列

考虑具有以下两个表的数据库。

员工表:

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(*) 很好,因为它实际上也不会返回任何列,因此只需要读取和处理那些用于过滤目的的列。