SQL查询所有列:SELECT *里的星号管列,不管行

发布时间:2026/10/6 12:10:03
SQL查询所有列:SELECT *里的星号管列,不管行 原题是牛客查询所有列。运营想查看用户信息表中的全部数据答案只有一行SELECT * FROM user_profile;这行 SQL 并不难。但如果把它记成“星号表示所有用户”下一题只取两列、只查一个学校时就容易分不清是谁控制什么。1. 先把表看成两个方向表有列也有行。列是每条记录包含哪些信息行是有哪些记录。选择哪些列 ------------ id device_id age ... ^ 1 2138 21 选择哪些行 | 2 3214 NULL v 3 6543 20SELECT后的列表决定返回哪些列FROM指定从哪里取WHERE决定留下哪些行。在这道单表题里*选择所有列。没有WHERE才是没有额外筛选行的原因。二者碰巧同时出现不代表是同一件事。2. 用完整数据跑一次下面是依照原题样例整理的可复现实验使用独立测试表不在业务数据库执行建表。CREATE TABLE user_profile ( id INTEGER PRIMARY KEY, device_id INTEGER, gender VARCHAR(10), age INTEGER, university VARCHAR(30), province VARCHAR(20) ); INSERT INTO user_profile (id, device_id, gender, age, university, province) VALUES (1, 2138, male, 21, 北京大学, Beijing), (2, 3214, male, NULL, 复旦大学, Shanghai), (3, 6543, female, 20, 北京大学, Beijing), (4, 2315, female, 23, 浙江大学, ZheJiang), (5, 5432, male, 25, 山东大学, Shandong);为了让本地输出便于逐行核对实验显式按唯一的id排序SELECT * FROM user_profile ORDER BY id;iddevice_idgenderageuniversityprovince12138male21北京大学Beijing23214maleNULL复旦大学Shanghai36543female20北京大学Beijing42315female23浙江大学ZheJiang55432male25山东大学Shandong原题没有排序要求最前面的一行答案即可。这里加ORDER BY是实验约定不能从一次没排序的输出推断数据库永远按插入顺序返回。第二行age是NULL这一行仍在结果里。查询全部记录不要求每个字段都有值也不会自动补零或去重。原笔记的运行结果保留如下它只代表当时平台提交不是本轮实验的截图3. 把列选择和行筛选分开试只要用户编号与学校但仍然取所有行SELECT device_id, university FROM user_profile ORDER BY id;仍是5行但只有2列。返回列的顺序就是这里写出的顺序。反过来保留所有列但只取北京大学的用户SELECT * FROM user_profile WHERE university 北京大学 ORDER BY id;现在是2行、6列对应id 1和id 3。所以“所有列”不等于“所有行”。再故意写一个没有匹配记录的条件SELECT * FROM user_profile WHERE id -1;结果是0行不是“有一行且所有值都是NULL”。客户端仍可获知这次查询的6个结果列结果结构与实际有几条记录是两个问题。4. 一个更实际的问题表加字段后星号会不会变先运行上面的查询再在测试表新增一个普通字段ALTER TABLE user_profile ADD COLUMN nickname VARCHAR(30);重新运行SELECT * FROM user_profile ORDER BY id;本地实验返回7列新增的nickname在已有行上为NULL。前面的显式两列查询仍然返回2列。变更前SELECT * - 6列 变更后SELECT * - 7列 变更后SELECT device_id, university - 2列这才是长期使用*值得注意的地方代码没有改结果结构却跟着表变了。例如调用方认为最后一列永远是province增加字段后这个约定就不成立了。按位置解包、CSV导出字段数、固定响应格式都可能受影响。临时排查、初学练习中*很方便长期接口只需要几个字段时明确写出字段更容易看出输出约定。它也不能代替授权和数据脱敏选列少不等于访问控制已经做好。这里的“全部”还有版本和表定义边界MySQL支持不可见列普通SELECT *不包含不可见列需要显式指定。上面的实验只新增普通列没有在SQLite中模拟MySQL的不可见列机制。见MySQL不可见列文档。也不能反过来背成“用了星号就一定慢”。是否多读了不需要的数据、是否能利用覆盖索引等要看具体查询和执行计划本文没有跑性能基准。5. 这篇怎么核对结果本地使用Python标准库的SQLite内存数据库直接执行本文SQL代码块而不是另写一份差不多的查询。核对原题5行6列、列名顺序、NULL保留、显式两列、筛选结果、空结果以及加字段后的6列变7列。还检查错误改写COUNT(*)得到的是一行统计值不是原表全部记录省掉FROM写SELECT *在该实验数据库中会报错。SQLite实验用于验证这些基础查询的结果结构不代表实测了MySQL的权限、排序规则、索引计划或不可见列。语法范围另外参照MySQL SELECT文档。这道题可以只交一行答案理解时却要保留两个方向先问要哪些列再问要哪些行。后面的查询题基本都在这两个方向上加条件。