SQL查询实战:高效数据检索全攻略

SQL DQL 详解:SELECT 查询与核心子句

DQL(Data Query Language)是 SQL 中最常用的部分,核心是 SELECT 语句,用于从数据库检索数据。以下是完整结构和各子句的详细解析:

SELECT [DISTINCT] column_list               -- 选择字段
FROM table_sources                          -- 数据来源
[JOIN_TYPE JOIN table ON join_condition]    -- 多表连接
[WHERE search_condition]                    -- 行级过滤
[GROUP BY grouping_columns]                 -- 数据分组
[HAVING group_condition]                    -- 分组过滤
[ORDER BY sort_columns [ASC|DESC]]          -- 结果排序
[LIMIT [offset,] row_count];                -- 行数限制

一、SELECT(字段列表)

功能:指定要检索的列或表达式

SELECT 
    first_name, 
    last_name, 
    salary * 1.1 AS new_salary  -- 使用表达式和别名
FROM employees;

关键点

  • * 选择所有列(生产环境慎用)
  • 使用 AS 赋予列别名(salary AS 月薪
  • DISTINCT 去重:SELECT DISTINCT department_id
  • 支持表达式:quantity * unit_price AS total

二、FROM(数据来源)

功能:指定查询的源表

FROM employees
FROM orders INNER JOIN customers  -- 多表查询

三、WHERE(行级过滤)

功能:基于条件筛选行

WHERE salary > 5000 
  AND department_id = 10
  AND hire_date >= '2023-01-01'

常用运算符

运算符示例说明
=id = 101等于
=> <=salary > 5000大小比较
BETWEEN ... AND ...age BETWEEN 20 AND 30范围查询
LIKEname LIKE 'J%'模式匹配(%任意字符,_单个字符)
IN(...)id IN (101, 102, 103)值列表匹配
IS NULLmanager_id IS NULL空值检查
AND/OR/NOTA AND B逻辑组合

四、JOIN(多表连接)

功能:组合多个表的数据

1. INNER JOIN(内连接)
SELECT employees.name, departments.dept_name
FROM employees
INNER JOIN departments 
  ON employees.dept_id = departments.id
  • 仅返回匹配的行(交集)
2. LEFT JOIN(左外连接)
SELECT customers.name, orders.amount
FROM customers
LEFT JOIN orders 
  ON customers.id = orders.customer_id
  • 返回左表所有行 + 右表匹配行(无匹配显示NULL)
3. 其他连接类型:
  • RIGHT JOIN:保留右表所有行
  • FULL OUTER JOIN:返回所有行(MySQL 需用 UNION 模拟)
  • CROSS JOIN:笛卡尔积(慎用)

五、GROUP BY(数据分组)

功能:将数据按列分组,用于聚合计算

SELECT 
    department_id,
    COUNT(*) AS employee_count,  -- 聚合函数
    AVG(salary) AS avg_salary
FROM employees
GROUP BY department_id

常用聚合函数

  • COUNT():计数
  • SUM():求和
  • AVG():平均值
  • MAX()/MIN():最大/最小值

重要规则

  • SELECT 中的非聚合列必须出现在 GROUP BY 中
  • 可以按多列分组:GROUP BY year, month

六、HAVING(分组过滤)

功能:对 GROUP BY 的分组结果进行过滤

SELECT department_id, AVG(salary)
FROM employees
GROUP BY department_id
HAVING AVG(salary) > 8000  -- 过滤分组

与 WHERE 的区别

特性WHEREHAVING
执行时机分组前分组后
可用的列原始列分组列/聚合结果
聚合函数❌ 不可用✅ 可用

七、ORDER BY(结果排序)

功能:对结果集排序

SELECT name, salary
FROM employees
ORDER BY 
    salary DESC,  -- 先按工资降序
    hire_date ASC  -- 再按入职日期升序

排序规则

  • ASC:升序(默认)
  • DESC:降序
  • 可排序表达式:ORDER BY LENGTH(name)
  • NULL 值处理:ORDER BY salary DESC NULLS LAST

八、LIMIT(行数限制)

功能:限制返回的行数(常用于分页)

SELECT 字段列表
FROM 表名
LIMIT 起始索引, 查询记录数;  -- 返回前10行

分页实现

LIMIT 10 OFFSET 20  -- 跳过前20行,取10行(第21-30行)
-- MySQL简写:LIMIT 20, 10  

注意

  • 起始索引从0开始,起始索引 = (查询页码-1) * 每页显示记录数。
  • 分页查询是数据库的方言,不同数据库有不同实现,MySQL中为LIMIT。
  • 如果查询的是第一页数据,起始索引可以省略,直接简写为limit10。

完整工作流程与执行顺序

  1. FROM:确定数据来源(表)
  2. JOIN:连接关联表
  3. WHERE:过滤符合条件的行
  4. GROUP BY:对数据进行分组
  5. HAVING:过滤分组结果
  6. SELECT:选择要返回的列
  7. ORDER BY:对结果排序
  8. LIMIT:限制返回行数
-- 完整示例:查询2023年销售额超10万的部门
SELECT 
    d.department_name,
    SUM(s.amount) AS total_sales
FROM sales s
INNER JOIN employees e ON s.employee_id = e.id
INNER JOIN departments d ON e.department_id = d.id
WHERE s.sale_date BETWEEN '2023-01-01' AND '2023-12-31'
GROUP BY d.department_id
HAVING total_sales > 100000
ORDER BY total_sales DESC
LIMIT 5;

关键要点

  1. WHERE 在 GROUP BY 前执行,不能使用聚合函数
  2. HAVING 可使用聚合函数,但效率低于 WHERE 提前过滤
  3. ORDER BY 可使用 SELECT 中定义的别名
  4. LIMIT 应始终与 ORDER BY 配合使用(确保顺序确定)
  5. 多表 JOIN 时使用表别名提高可读性
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值