SQL常见问题整理(一)

1.从表中查询数据

(1)指定查询的行与列
where子句
(2)指定查询结果中列的别名
as
注:不能在where子句中使用列别名
(3)查询结果排序
order by
降序排序在排序字段后加DESC
自定义排序:使用field()将列值映射到一个序列中,该序列可以按照所需的排序为列赋值order by field(name,‘Henry’,‘Suzi’,‘Ben’)
(4)过滤重复行
distinct
统计唯一结果的数量 count(distinct A)
(5)处理NULL值
is null、is not null、<=>、<>
(6)多表查询
join…on…
(7)截取查询结果的开头、末尾或中间部分
limit,根据需要与order by结合使用。先order by 再limit,order by可以使用列别名。
选取结果集中间的某些行,可以使用带有两个参数的limit,这样可以选择任意行,表示跳过的行数和返回的行数,如limit2,1 表示跳过两行然后返回下一行
可以完成诸如“第三小或第三大的值”等查询,min()或max()无法完成这类的查询

2.表管理

(1)克隆表
create table…like来克隆表的结构,将原表的部分或全部数据复制到新表,可以使用insert into … select
新表结构与原表相同,新表没有数据:create table new_table like original_table
新表拥有与原表相同的数据(先create创建表new_table再insert into):insert into new_table select * from original_table
(2)使用临时表
temporary

3.字符串

(1)转换字符串的大小写
upper()或lower()函数
如果upper()或lower()不起作用,可能字符串是二进制字符串,需要将它转换成拥有字符集和排序规则的非二进制字符串
只把首字母大写:concat(upper(left(str,1)),mid(str,2))
(2)使用正则表达式进行模式匹配
以特定子字符串开头的字符串:select name from metal where name regexp ‘^me’
以特定子字符串结尾的字符串:select name from metal where name regexp ‘d$’
任意位置包含特定子字符串的字符串:select name from metal where name regexp ‘in’
特定位置包含子字符串的字符串:select name from metal where name regexp ‘^…at’
(3)分割或连接字符串
连接:concat(A,’@’,B)
提取:
从左侧开始数,起始字符串开始返回左侧所有内容(包括起始字符串):left(A,4)
从右侧开始数,从起始字符串开始返回右侧所有内容(包括起始字符串):right(A,2)
从左侧开始数,起始字符串右侧所有内容(包括起始字符串):substring(A,6)或mid(A,6)
从左侧开始数,起始字符串右侧指定字符串数量(包括起始字符串):
substring(s,n,len)或mid(s,n,len)
substring(A,6,2)或mid(A,6,2)
返回指定字符串左侧或右侧的所有内容:substring_index(str,c,n) str字符串中第n次出现的字符c
substring(str,’@’,1) ‘@‘左侧全部内容
substring(str,’@’,-1) '@'右侧全部内容
(4)搜索子字符串
locate()或模式匹配
返回子串出现的位置,如果不存在返回0:locate(‘in’,name)
第三个可选参数表示从字符串的哪个位置开始查找:locate(‘in’,name,3)

4.日期与时间

(1)选择时间数据类型
日期:date()
时间值:time()
日期和时间的结合值:datetime()、timestamp()
(2)更改MySQL的日期格式
date_format(d,’%M %d,%Y’)
两个参数,第一个是date,datetime,timestamp类型的值,另一个是显示格式的字符串。
time_format(dt,’%r’)
两个参数,第一个是date,datetime,timestamp类型的值,另一个是显示格式的字符串,但只处理格式字符串中与时间相关的部分

格式化字符含义
%Y年份,四位数字
%y年份,后两位数字
%M完整的月份名称(January…December)
%b月份名称,头三个字母(Jan…Dec)
%m月份,两位数字(01…12)
%c月份(1…12)
%d月份中的天数,两位数字(01…31)
%e月份中的天数,(1…31)
%W星期的名字(Sunday-Saturday)
%r时间,12小时制,以AM或PM结尾
%T时间,24小时制
%H小时,两位数字(00…23)
%i分钟,两位数字(00…59)
%s秒钟,两位数字(00…59)
%%字母“%”

(3)获取当前的日期或时间
当前的日期或时间值:curdate()、curtime()、now()
utc时间值:utc_date()、utc_time()、utc_timestamp()
(4)追踪行的修改时间
使用timestamp和datetime数据类型的自动初始化和自动更新属性
(5)提取日期或时间值的各部分
提取时间值函数:

函数返回值
YEAR()返回年份
MONTH()返回月份 (1…12)
MONTHNAME()返回月份全名(January…December)
DAYOFMONTH()返回月份中的天数(1…31)
DAYNAME()返回星期的名字(Sunday…Saturday)
DAYOFWEEK返回星期中的天数(Sunday…Saturday分别为1…7)
WEEKDAY()返回星期中的天数(Monday…Sunday分别为0…6)
DAYOFYEAR()返回一年中的天数(1…366)
HOUR()返回小时(00…23)
MINUTE()返回分钟(00…59)
SECOND()返回秒钟(00…59)
EXTRACT()返回日期中的相应部分 (year、month、day等都可以)

与日期相关的函数适用date、datetime、timestamp
与时间相关的函数适用time、datetime、timestamp
格式化函数:
格式化日期:date_format(dt,’%Y-%m-%d’)
格式化时间:time_format(dt,’%H’)
(6)合成日期或时间值
根据小时、分和秒合成time值:maketime(10,30,58) 返回 10:30:58
利用现有的值,再加上想替换的部分,共同组成新的日期或时间:
date_format(d,’%Y-%m-01’)
time_format(t1,’%H:%i:00’)
使用日期提取函数将所需部分抽出来,再通过concat()重新组合在一起:
concat(year(d),’-’,lpad(month(d),2,‘0’),’-01’) (lpad函数用于填充0,保证月份用两位数展现)
(7)时间值和基本单位之间的转换
时间值和秒之间转换:time_to_sec()、sec_to_time()
日期值和天之间转换:to_days()、from_days()
时间值与秒之间转换:unix_timestamp()、from_unixtime()
(8)计算日期或时间之间的间隔
时间差函数:datediff(d1,d2) d1-d2
datediff(d2,d1) d2-d1
将时间值转换成基本单位再求差:timestampdiff(unit,val1,val2) unit是间隔单位,val1和val2是计算间隔的值val1-val2,unit可以指定为microsecond、second、minute、hour、day、week、month、quarter或year
(9)日期或时间值的加法运算
①使用时间加法函数:
两个时间或时间与日期时间值的总和(不能加日期):
addtime(t1,t2) t1+t2
addtime(dt,t) dt+t
时间与日期,时间与日期时间值的总和(可以加日期):
timestamp(d,t) d+t
timestamp(dt,t) dt+t
②使用+interval或-interval运算符
unit是间隔单位,val有多少个单位
加:date_add(d,interval val unit)
减:date_sub(d,interval val unit)

<think>好的,我现在需要处理用户的问题:“请使用中文回答我或者给我介绍下: sql常见面试问题”。用户之前已经询问过关于Linux三剑客的问题,现在转向SQL面试问题,可能是在准备技术面试,尤其是数据库相关的职位。我需要确保回答结构清晰,覆盖常见的SQL面试问题,同时保持内容准确可靠。 首先,我应该考虑用户的潜在需求。他们可能希望了解在面试中可能会遇到的SQL问题,包括基本概念、查询语句、函数、连接、优化等方面的问题。需要分门别类,每个类别下给出具体的问题和简要解答,帮助用户全面准备。 接下来,我需要确定回答的结构。通常,这类问题可以分为基础概念、查询与操作、函数与聚合、表连接与子查询、性能优化、事务与锁、设计相关以及其他高级问题等部分。每个部分列出几个常见问题,并给出简短的答案或示例,这样用户能够快速理解和记忆。 在基础概念部分,需要包括SQL和NoSQL的区别、主键与外键、事务的特性(ACID)等。这些是面试中常见的基础问题,用户需要明确这些概念才能应对后续更复杂的问题。 查询与操作部分,应涵盖SELECT语句的执行顺序、WHERE和HAVING的区别、DELETE/TRUNCATE/DROP的区别。这些都是SQL的基本操作,面试中经常被问到,尤其是执行顺序和不同删除操作的差异。 函数与聚合部分,COUNT(*)和COUNT(列名)的区别、窗口函数的用途、GROUP BY的使用场景需要解释清楚。特别是窗口函数在数据分析中的应用越来越广泛,用户需要了解其基本用法。 表连接与子查询部分,JOIN的类型和区别、内连接与外连接的区别、EXISTS和IN的使用场景是关键。这些内容涉及SQL的高级查询,是面试中的重点。 性能优化方面,索引的作用及优缺点、如何优化慢查询、执行计划的解读是必问的问题。用户需要知道如何通过索引和查询优化提高数据库性能。 事务与锁部分,事务的隔离级别、死锁的产生和避免方法是数据库并发控制的核心内容,面试中常被考察。 设计相关的问题包括范式的理解、主键设计原则、分库分表的使用场景。这些涉及数据库设计,用户需要了解规范化和实际应用中的权衡。 其他高级问题可能包括存储过程、触发器、游标的优缺点,以及如何处理重复数据。这些问题考察用户的实际经验和问题解决能力。 最后,需要给出学习建议,比如多练习LeetCode或HackerRank上的题目,理解执行计划,掌握优化技巧等,帮助用户进步准备。 在组织内容时,要确保每个问题都有明确的答案,并且使用示例代码(如SQL语句)来增强理解。同时,注意使用中文,避免技术术语的直译,保持口语化但专业。检查是否有遗漏的重要问题,并确保覆盖SQL面试的主要方面。例如,是否需要提到窗口函数的具体例子,或者更多的优化策略? 另外,考虑到用户可能对某些概念不太熟悉,解释时需要简明扼要,避免过于冗长。例如,在解释ACID时,用简短的定义说明每个特性的含义,而不是深入讨论实现细节。 最后,总结部分可以用表格形式对比不同概念,帮助用户记忆。同时,提醒用户实际操作和理论结合的重要性,建议他们通过实际练习巩固知识。 现在,将这些思考整理个结构清晰、内容详实的回答,确保符合用户的需求,帮助他们在SQL面试中做好准备。</think>以下是 SQL 常见面试问题的整理,涵盖基础语法、查询优化、设计原理等核心内容,帮助系统化备战面试: --- ### 、**基础概念** 1. **SQL 与 NoSQL 的区别** - SQL(关系型数据库):结构化数据、ACID 事务、强致性(如 MySQL、PostgreSQL)。 - NoSQL(非关系型):半/非结构化数据、高扩展性、弱致性(如 MongoDB、Redis)。 2. **主键(Primary Key)与外键(Foreign Key)** - 主键:唯标识行,不可重复且非空(如 `id INT PRIMARY KEY`)。 - 外键:关联其他表的主键,保证引用完整性(如 `user_id INT REFERENCES users(id)`)。 3. **事务的 ACID 特性** - **原子性**(Atomicity):事务全部成功或全部回滚。 - **致性**(Consistency):事务前后数据状态合法。 - **隔离性**(Isolation):并发事务互不干扰。 - **持久性**(Durability):事务提交后数据永久保存。 --- ### 二、**查询与操作** 4. **SELECT 语句的执行顺序** ```sql FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY → LIMIT ``` 5. **WHERE 和 HAVING 的区别** - `WHERE`:过滤行,在聚合前执行。 - `HAVING`:过滤分组,在聚合后执行(需配合 `GROUP BY`)。 6. **DELETE、TRUNCATE、DROP 的区别** - `DELETE`:逐行删除,可回滚,触发触发器。 - `TRUNCATE`:清空表,重置自增列,不可回滚。 - `DROP`:删除表结构及数据。 --- ### 三、**函数与聚合** 7. **COUNT(*) 和 COUNT(列名) 的区别** - `COUNT(*)`:统计所有行(包括 `NULL`)。 - `COUNT(列名)`:统计非 `NULL` 值的行数。 8. **窗口函数(Window Function)的作用** - 在分组内计算而不合并结果(如排名、累计值): ```sql SELECT name, salary, RANK() OVER (ORDER BY salary DESC) AS rank FROM employees; ``` 9. **GROUP BY 的使用场景** - 按指定列分组后聚合(如统计部门平均工资): ```sql SELECT department, AVG(salary) FROM employees GROUP BY department; ``` --- ### 四、**表连接与子查询** 10. **JOIN 的类型及区别** - **INNER JOIN**:返回两表匹配的行。 - **LEFT JOIN**:返回左表全部行 + 右表匹配的行(右表无匹配则为 `NULL`)。 - **FULL JOIN**:返回两表所有行(无匹配则为 `NULL`)。 11. **EXISTS 和 IN 的适用场景** - `EXISTS`:检查子查询是否有结果,适合关联子查询(效率更高)。 - `IN`:匹配子查询的固定值列表,适合静态值过滤。 --- ### 五、**性能优化** 12. **索引的作用及优缺点** - 作用:加速查询,减少全表扫描。 - 优点:提高 `WHERE`、`JOIN`、`ORDER BY` 速度。 - 缺点:降低写操作速度,占用存储空间。 13. **如何优化慢查询** - 添加索引(避免全表扫描)。 - 避免 `SELECT *`,减少返回字段。 - 拆分复杂查询,优化子查询。 14. **如何查看 SQL 执行计划** - 使用 `EXPLAIN` 分析查询路径: ```sql EXPLAIN SELECT * FROM users WHERE age > 30; ``` --- ### 六、**事务与锁** 15. **事务的隔离级别** - 读未提交 → 读已提交 → 可重复读 → 串行化(隔离性递增,并发性递减)。 16. **死锁的产生与避免** - 产生:多个事务互相等待对方释放锁。 - 避免:按固定顺序访问资源,设置超时机制。 --- ### 七、**设计相关** 17. **数据库三大范式** - 1NF:列不可再分。 - 2NF:消除部分依赖(主键唯决定其他字段)。 - 3NF:消除传递依赖(非主键字段不相互依赖)。 18. **主键设计原则** - 唯性、非空、简洁(如自增整数或 UUID)。 19. **何时使用分库分表** - 单表数据量过大(如千万级)、高并发读写、业务模块解耦。 --- ### 八、**其他高频问题** 20. **存储过程、触发器、游标的优缺点** - 存储过程:预编译 SQL,提高复用性,但调试困难。 - 触发器:自动执行逻辑,可能引发连锁更新。 - 游标:逐行处理数据,效率低,尽量少用。 21. **如何删除重复数据** ```sql -- 使用窗口函数标记重复行 DELETE FROM users WHERE id IN ( SELECT id FROM ( SELECT id, ROW_NUMBER() OVER (PARTITION BY email ORDER BY id) AS rn FROM users ) t WHERE t.rn > 1 ); ``` --- ### 总结与学习建议 | **分类** | **重点问题** | |----------------|--------------------------------------| | 基础语法 | SELECT 执行顺序、JOIN 类型、ACID | | 查询优化 | 索引、执行计划、慢查询优化 | | 设计原理 | 范式、分库分表、主键设计 | | 高级特性 | 窗口函数、事务隔离级别、死锁处理 | **学习建议**: 1. 刷题平台:LeetCode、HackerRank 的 SQL 题库。 2. 深入理解执行计划(`EXPLAIN`)。 3. 掌握至少种数据库的优化工具(如 MySQL 的 `SHOW PROFILE`)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值