高级sql技巧

高级SQL技巧涵盖了多个方面,包括窗口函数、递归查询、公用表表达式(CTE)、子查询、集合操作等。

一、窗口函数

窗口函数允许用户在一组行(称为窗口)上执行计算,而不会将这些行合并成单个结果行。在处理排名、累计和运行总和等场景中非常有用。

案例

假设有一个员工表(employees),包含员工ID(employee_id)、部门ID(department_id)和薪水(salary)等字段。现在想要查询每个部门内员工的薪水排名、薪水等级(允许并列)和连续等级(不允许并列)。

SELECT
    employee_id,
    department_id,
    salary,
    ROW_NUMBER() OVER (PARTITION BY department_id ORDER BY salary DESC) AS row_num,
    RANK() OVER (PARTITION BY department_id ORDER BY salary DESC) AS rank,
    DENSE_RANK() OVER (PARTITION BY department_id ORDER BY salary DESC) AS dense_rank
FROM
    employees;

说明

  • ROW_NUMBER():为每个部门的员工按薪水降序分配一个唯一的序号。
  • RANK():为每个部门的员工按薪水降序分配一个等级,允许并列,并列后的等级会跳过。
  • DENSE_RANK():为每个部门的员工按薪水降序分配一个连续等级,不允许并列。

二、递归查询

递归查询允许用户在一个查询中多次引用同一个表,这在处理树形结构数据(如组织架构、目录结构)时非常有用。

案例

假设有一个员工表(employees),包含员工ID(employee_id)、经理ID(manager_id)等字段。现在想要查询每个员工的所有上级经理,直到最高级经理(没有经理的经理)。

WITH RECURSIVE EmployeeCTE AS (
    SELECT
        employee_id,
        manager_id,
        1 AS level
    FROM
        employees
    WHERE
        manager_id IS NULL
    UNION ALL
    SELECT
        e.employee_id,
        e.manager_id,
        ecte.level + 1
    FROM
        employees e
    INNER JOIN
        EmployeeCTE ecte ON e.manager_id = ecte.employee_id
)
SELECT
    employee_id,
    manager_id,
    level
FROM
    EmployeeCTE
ORDER BY
    level,
    employee_id;

说明

  • WITH RECURSIVE EmployeeCTE AS (...):定义一个递归公用表表达式(CTE)。
  • 初始查询部分:选择最高级经理(没有经理的经理)。
  • 递归查询部分:通过内连接将员工表与CTE进行连接,查找每个员工的上级经理,并增加层级(level)。

三、公用表表达式(CTE)

CTE是一种临时的结果集,只在单个查询的执行周期内有效。它有助于使复杂查询更加易读和易维护。

案例

假设有一个销售表(sales),包含员工ID(employee_id)和销售金额(amount)等字段。现在想要查询总销售金额超过10000的员工ID和总销售金额。

WITH SalesCTE AS (
    SELECT
        employee_id,
        SUM(amount) AS total_sales
    FROM
        sales
    GROUP BY
        employee_id
)
SELECT
    employee_id,
    total_sales
FROM
    SalesCTE
WHERE
    total_sales > 10000;

说明

  • WITH SalesCTE AS (...):定义一个公用表表达式(CTE),计算每个员工的总销售金额。
  • 在主查询中引用CTE,并筛选总销售金额超过10000的员工。

四、子查询

子查询是嵌套在另一个查询中的查询,常用于筛选条件和数据过滤。

案例

假设有一个员工表(employees),包含员工ID(employee_id)和薪水(salary)等字段。现在想要查询薪水高于公司平均薪水的员工ID和薪水。

SELECT
    employee_id,
    salary
FROM
    employees
WHERE
    salary > (SELECT AVG(salary) FROM employees);

说明

  • 子查询 (SELECT AVG(salary) FROM employees):计算公司平均薪水。
  • 主查询筛选薪水高于平均薪水的员工。

五、集合操作

集合操作允许用户将两个或多个查询结果集进行合并或比较。常见的集合操作符包括UNION、INTERSECT和EXCEPT。

案例

假设有两个表:客户表(customers)和供应商表(suppliers),都包含姓名(name)字段。现在想要查询所有客户和供应商的姓名(去重),以及同时是客户和供应商的姓名,还有只是客户的姓名(不是供应商)。

-- 合并两个查询结果集(去重)
SELECT name FROM customers
UNION
SELECT name FROM suppliers;

-- 找出两个查询结果集的交集
SELECT name FROM customers
INTERSECT
SELECT name FROM suppliers;

-- 找出只在第一个查询结果集中存在的记录
SELECT name FROM customers
EXCEPT
SELECT name FROM suppliers;

说明

  • UNION:合并两个查询结果集,并去除重复记录。
  • INTERSECT:找出两个查询结果集的交集,即同时出现在两个结果集中的记录,并去除重复记录。
  • EXCEPT:找出只在第一个查询结果集中存在的记录,即出现在第一个结果集中但不出现在第二个结果集中的记录,并去除重复记录。

总结

这些高级SQL技巧在实际应用中非常有用,能够帮助开发者更高效地处理复杂的数据查询和分析任务。

相关推荐
不爱学英文的码字机器几秒前
在 Linux 中如何使用粘滞位 (t-bit)共享文件
linux·服务器·数据库
小扳32 分钟前
微服务篇-深入了解 XXL-JOB 分布式任务调度的具体使用(XXL-JOB 的工作流程、框架搭建)
数据库·分布式·spring·spring cloud·微服务·架构
drebander39 分钟前
SQL 实战:正则表达式匹配 – 高效数据筛选与文本解析
数据库·sql·正则表达式
唐可盐41 分钟前
图文教程:使用PowerDesigner导出数据库表结构为Word/Html文档
数据库
web137656076431 小时前
【MySQL】深度学习数据库开发技术:使用CC++语言访问数据库
数据库·mysql·数据库开发
lucky_syq1 小时前
MySQL和HBase的对比
数据库·mysql·hbase
丁总学Java1 小时前
要查询 `user` 表中 `we_chat_subscribe` 和 `we_chat_union_id` 列不为空的用户数量
数据库·mysql·微信小程序
张声录11 小时前
【ETCD】【实操篇(十七)】 etcd 集群定期维护指南
数据库·etcd
被猫枕的咸鱼2 小时前
【免费分享】mysql笔记,涵盖查询、缓存、存储过程、索引,优化。
笔记·mysql·缓存
岚精灵玩电脑2 小时前
Spring自动化创建脚本-解放繁琐的初始化配置!!!(自动化SSM整合)
数据库·spring·自动化