10个高级的 SQL 查询技巧.

1、常见表表达式(CTEs)

如果您想要查询子查询,那就是CTEs施展身手的时候 - CTEs基本上创建了一个临时表。
使用常用表表达式(CTEs)是模块化和分解代码的好方法,与您将文章分解为几个段落的方式相同。
请在Where子句中使用子查询进行以下查询。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
SELECT
name,
salary
FROM
People
WHERE
NAMEIN(SELECTDISTINCTNAMEFROMpopulationWHEREcountry="Canada"ANDcity="Toronto")
ANDsalary>=(
SELECT
AVG(salary)
FROM
salaries
WHERE
gender="Female")

这似乎似乎难以理解,但如果在查询中有许多子查询,那么怎么样?这就是CTEs发挥作用的地方。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
with toronto_ppl as (
SELECT DISTINCT name
FROM population
WHERE country = "Canada"
AND city = "Toronto"
)
, avg_female_salary as (
SELECT AVG(salary) as avgSalary
FROM salaries
WHERE gender = "Female"
)
SELECT name
, salary
FROM People
WHERE name in (SELECT DISTINCT FROM toronto_ppl)
AND salary >= (SELECT avgSalary FROM avg_female_salary)

现在很清楚,Where子句是在多伦多的名称中过滤。如果您注意到,CTE很有用,因为您可以将代码分解为较小的块,但它们也很有用,因为它允许您为每个CTE分配变量名称(即toronto_ppl和avg_female_salary)同样,CTEs允许您完成更高级的技术,如创建递归表。

2 递归CTEs.

递归CTE是引用自己的CTE,就像Python中的递归函数一样。递归CTE尤其有用,它涉及查询组织结构图,文件系统,网页之间的链接图等的分层数据,尤其有用。递归CTE有3个部分:
锚构件:返回CTE的基本结果的初始查询递归成员:引用CTE的递归查询。这是所有与锚构件的联盟停止递归构件的终止条件以下是获取每个员工ID的管理器ID的递归CTE的示例:

1
2
3
4
5
6
7
8
9
10
with  org_structure  as  (
SELECT id, manager_id
FROM staff_members
WHERE manager_id IS NULL
UNION ALL
SELECT sm.id, sm.manager_id
FROM staff_members sm
INNER JOIN org_structure os
ON os.id = sm.manager_id

3、临时函数

如果您想了解有关临时函数的更多信息,请检查此项,但知道如何编写临时功能是重要的原因:

1.它允许您将代码的块分解为较小的代码块
2.它适用于写入清洁代码
3.它可以防止重复,并允许您重用类似于使用Python中的函数的代码。

考虑以下示例:

1
2
3
4
5
6
7
8
SELECT name, 
CASE WHEN tenure < 1 THEN "analyst"
WHEN tenure BETWEEN 1 and 3 THEN "associate"
WHEN tenure BETWEEN 3 and 5 THEN "senior"
WHEN tenure > 5 THEN "vp"
ELSE "n/a"
END AS seniority
FROM employees

临时函数来捕获案例子句:

1
2
3
4
5
6
7
8
9
10
11
CREATE TEMPORARY FUNCTION get_seniority(tenure INT64) AS (
CASE WHEN tenure < 1 THEN "analyst"
WHEN tenure BETWEEN 1 and 3 THEN "associate"
WHEN tenure BETWEEN 3 and 5 THEN "senior"
WHEN tenure > 5 THEN "vp"
ELSE "n/a"
END
);
SELECT name
, get_seniority(tenure) as seniority
FROM employees

4 Rank vs Dense Rank vs Row Number

在SQL中,您可以使用几种方式将“等级”分配给行,我们将使用示例进行探索。考虑以下Query和结果:

1
2
3
4
5
6
SELECT  Name    
, GPA
, ROW_NUMBER() OVER (ORDER BY GPA desc)
, RANK() OVER (ORDER BY GPA desc)
, DENSE_RANK() OVER (ORDER BY GPA desc)
FROM student_grades

ROW_NUMBER()返回每行开始的唯一编号。当存在关系时(例如,BOB vs Carrie),ROW_NUMBER()如果未定义第二条标准,则任意分配数字。Rank()返回从1开始的每行的唯一编号,除了有关系时,Rank()将分配相同的数字。同样,差距将遵循重复的等级。dense_rank()类似于Rank(),除了重复等级后没有间隙。请注意,使用dense_rank(),Daniel排名第3,而不是第4位。


10个高级的 SQL 查询技巧.
http://example.com/2024/08/23/MySqlSummary04/
作者
JunCCore
发布于
2024年8月24日
许可协议
BY-JUNCCORE