SQL 最常用技能详解与实战示例
引言
SQL(Structured Query Language,结构化查询语言)是与关系型数据库交互的核心工具。无论是数据分析师、后端开发工程师还是产品经理,掌握 SQL 的核心技能都至关重要。本文将系统性地介绍 SQL 中最常用、最核心的技能,并通过清晰的示例帮助你快速上手和巩固。
1. 数据查询基础:SELECT 与 FROM
SELECT和FROM是 SQL 的基石,用于从表中检索数据。
核心语法:
SELECT列名1,列名2,...FROM表名;示例:
假设我们有一个employees表(员工表),包含id,name,department,salary等列。
-- 查询所有员工的所有信息SELECT*FROMemployees;-- 查询所有员工的姓名和部门SELECTname,departmentFROMemployees;2. 数据过滤:WHERE 子句
WHERE子句用于根据指定条件过滤记录。
核心语法:
SELECT列名FROM表名WHERE条件;常用运算符:
=:等于>,<,>=,<=:比较<>或!=:不等于BETWEEN ... AND ...:在某个范围内LIKE:模糊匹配(%匹配任意字符,_匹配单个字符)IN (...):在列表中IS NULL:是空值
示例:
-- 查询销售部门的所有员工SELECT*FROMemployeesWHEREdepartment='Sales';-- 查询薪资大于 50000 的员工姓名SELECTnameFROMemployeesWHEREsalary>50000;-- 查询姓名以 ‘张’ 开头的员工SELECT*FROMemployeesWHEREnameLIKE'张%';-- 查询部门为 ‘Sales’ 或 ‘Marketing’ 的员工SELECT*FROMemployeesWHEREdepartmentIN('Sales','Marketing');3. 数据排序:ORDER BY 子句
ORDER BY子句用于对结果集进行排序,默认升序(ASC),降序使用DESC。
核心语法:
SELECT列名FROM表名ORDERBY列名1[ASC|DESC],列名2[ASC|DESC];示例:
-- 按薪资从高到低排序所有员工SELECTname,salaryFROMemployeesORDERBYsalaryDESC;-- 先按部门升序排列,同部门内按薪资降序排列SELECTname,department,salaryFROMemployeesORDERBYdepartmentASC,salaryDESC;4. 数据聚合与分组:GROUP BY 与聚合函数
聚合函数对一组值执行计算并返回单个值。GROUP BY子句将结果集按一列或多列分组,常与聚合函数一起使用。
常用聚合函数:
COUNT():计数SUM():求和AVG():求平均值MAX():求最大值MIN():求最小值
核心语法:
SELECT聚合函数(列名),分组列FROM表名GROUPBY分组列;示例:
-- 统计每个部门的员工数量SELECTdepartment,COUNT(*)asemployee_countFROMemployeesGROUPBYdepartment;-- 计算每个部门的平均薪资和最高薪资SELECTdepartment,AVG(salary)asavg_salary,MAX(salary)asmax_salaryFROMemployeesGROUPBYdepartment;5. 分组后过滤:HAVING 子句
WHERE子句在分组前过滤行,而HAVING子句在分组后过滤分组结果。
核心语法:
SELECT聚合函数(列名),分组列FROM表名GROUPBY分组列HAVING分组后条件;示例:
-- 查询员工数量超过 5 人的部门SELECTdepartment,COUNT(*)asemployee_countFROMemployeesGROUPBYdepartmentHAVINGCOUNT(*)>5;-- 查询平均薪资超过 60000 的部门SELECTdepartment,AVG(salary)asavg_salaryFROMemployeesGROUPBYdepartmentHAVINGAVG(salary)>60000;6. 数据连接:JOIN
JOIN用于根据两个或多个表之间的相关列合并行。这是处理关系型数据的核心技能。
常用 JOIN 类型:
INNER JOIN:返回两个表中匹配的行。LEFT (OUTER) JOIN:返回左表的所有行,以及右表中匹配的行。不匹配的右表部分为 NULL。RIGHT (OUTER) JOIN:返回右表的所有行,以及左表中匹配的行。不匹配的左表部分为 NULL。FULL (OUTER) JOIN:返回两个表中所有的行,不匹配的部分为 NULL。
核心语法:
SELECT列名FROM表AJOIN表BON表A.关联列=表B.关联列;示例:
假设我们还有一个orders表(订单表),包含order_id,employee_id,amount等列,通过employee_id与employees表关联。
-- 查询所有员工及其订单信息(内连接,只显示有订单的员工)SELECTe.name,e.department,o.order_id,o.amountFROMemployees eINNERJOINorders oONe.id=o.employee_id;-- 查询所有员工,以及他们的订单信息(左连接,即使员工没有订单也会显示)SELECTe.name,e.department,o.order_id,o.amountFROMemployees eLEFTJOINorders oONe.id=o.employee_id;7. 子查询
子查询是嵌套在其他 SQL 查询中的查询。它可以出现在SELECT、FROM、WHERE或HAVING子句中。
示例:
-- 在 WHERE 子句中使用子查询:查询薪资高于平均薪资的员工SELECTname,salaryFROMemployeesWHEREsalary>(SELECTAVG(salary)FROMemployees);-- 在 FROM 子句中使用子查询(派生表)SELECTdept_stats.department,dept_stats.avg_salFROM(SELECTdepartment,AVG(salary)asavg_salFROMemployeesGROUPBYdepartment)ASdept_statsWHEREdept_stats.avg_sal>50000;8. 数据操作:INSERT, UPDATE, DELETE
除了查询,SQL 也用于操作数据。
INSERT(插入数据):
-- 插入一行完整数据INSERTINTOemployees(id,name,department,salary)VALUES(101,'张三','Engineering',75000);-- 插入多行数据INSERTINTOemployees(id,name,department,salary)VALUES(102,'李四','Sales',60000),(103,'王五','Marketing',55000);UPDATE(更新数据):
-- 将员工 ‘张三’ 的部门更新为 ‘Management’UPDATEemployeesSETdepartment='Management'WHEREname='张三';-- 为所有销售部门的员工加薪 10%UPDATEemployeesSETsalary=salary*1.10WHEREdepartment='Sales';DELETE(删除数据):
-- 删除 id 为 101 的员工DELETEFROMemployeesWHEREid=101;-- 删除所有薪资低于 30000 的员工(谨慎使用!)DELETEFROMemployeesWHEREsalary<30000;9. 数据定义:CREATE TABLE, ALTER TABLE, DROP TABLE
这些语句用于定义和修改数据库结构。
CREATE TABLE(创建表):
CREATETABLEemployees(idINTPRIMARYKEY,nameVARCHAR(100)NOTNULL,departmentVARCHAR(50),salaryDECIMAL(10,2),hire_dateDATEDEFAULTCURRENT_DATE);ALTER TABLE(修改表结构):
-- 添加一个新列ALTERTABLEemployeesADDCOLUMNemailVARCHAR(255);-- 修改列的数据类型ALTERTABLEemployeesALTERCOLUMNsalaryTYPEDECIMAL(12,2);-- 删除一个列ALTERTABLEemployeesDROPCOLUMNemail;DROP TABLE(删除表):
-- 删除表(极其危险,会丢失所有数据)DROPTABLEemployees;总结
掌握以上 SQL 技能,你就能应对日常工作中 80% 以上的数据库操作需求。核心路径是:查询(SELECT) -> 过滤(WHERE) -> 排序(ORDER BY) -> 聚合分组(GROUP BY/HAVING) -> 连接(JOIN)。数据操作(增删改)和表结构操作(DDL)则用于维护数据本身。
建议在本地安装 MySQL、PostgreSQL 或使用在线 SQL 练习平台,结合本文的示例进行实操,是掌握 SQL 最快的方式。
