使用通配符选择查询中的所有列
考虑具有以下两个表的数据库。
员工表:
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(*)
很好,因为它实际上也不会返回任何列,因此只需要读取和处理那些用于过滤目的的列。