混个眼熟,来见见SQL中那些不常见的关键字

在日常SQL开发中,我们经常使用SELECTUPDATEDELETEINSERT等常见关键字,但SQL标准中还有许多不常见却非常实用的关键字,这些关键字在特定场景下可以极大地优化查询性能或提供额外功能。本文将介绍一些鲜为人知但值得掌握的SQL关键字,并通过查询示例加深理解。

目录

1 LATERAL

2 WINDOW

3 MATCH_RECOGNIZE

4 DISTINCT ON

5 EXCEPT

6 UNNEST

7 ARRAY_AGG

8 CUBE

9 ROLLUP

10 JSON_TABLE


1 LATERAL

LATERAL关键字用于在FROM子句的子查询中引用外部查询的列,这种机制允许SQL语句中的子查询获取与主查询相关的记录。通常情况下,子查询不能直接访问外部查询的列,而LATERAL可以突破这一限制,使查询更加灵活。它在处理复杂的多表关联、动态过滤数据或展开JSON数据时非常有用。

id name contract
1 Alice {"type": "full-time"}
2 Bob {"type": "part-time"}
SELECT e.id, e.name, c.contract_type
FROM employees e,
LATERAL (
    SELECT contract->>'type' AS contract_type
) c;

2 WINDOW

WINDOW关键字用于定义窗口函数的窗口分区,使得多个窗口函数可以共享同一个窗口定义。这样可以避免在多个窗口函数中重复书写相同的PARTITION BYORDER BY子句,提高查询的可读性和效率。窗口函数常用于分析函数,例如计算累计总和、排名或移动平均值。

name department salary
Alice Engineering 8000.00
Bob HR 6000.00
SELECT name, department, salary,
       AVG(salary) OVER emp_window AS avg_salary
FROM employees
WINDOW emp_window AS (PARTITION BY department ORDER BY hire_date);

3 MATCH_RECOGNIZE

MATCH_RECOGNIZE关键字用于模式匹配查询,主要用于时间序列分析、数据流处理或检测异常模式。它允许定义模式规则,并使用PATTERNDEFINE语句对数据进行模式识别,使得SQL能够像正则表达式一样匹配数据模式,特别适用于检测趋势、变化点或异常。

id name salary
1 Alice 8000.00
2 Bob 6000.00
SELECT * FROM employees
MATCH_RECOGNIZE (
    ORDER BY hire_date
    MEASURES id AS emp_id, name AS emp_name
    PATTERN (A B)
    DEFINE A AS salary > 7000, B AS salary < 7000
);

4 DISTINCT ON

DISTINCT ON用于从重复数据中仅选取某个分组中的第一条记录。与GROUP BY不同,它允许我们在有序数据集中获取特定类别的第一条数据,在去重的同时保留一定的排序逻辑,适用于获取最近更新的记录或按优先级筛选数据。

department name hire_date
Engineering Alice 2020-05-15
HR Bob 2019-07-23
SELECT DISTINCT ON (department) *
FROM employees
ORDER BY department, hire_date DESC;

5 EXCEPT

EXCEPT关键字用于计算两个查询结果的差集,即返回出现在第一个查询但未出现在第二个查询中的记录。它类似于NOT IN,但在处理大数据集时更高效,特别适用于数据去重和数据完整性验证。

name department salary
Alice Engineering 8000.00
David Engineering 9500.00
SELECT name FROM employees WHERE department = 'Engineering'
EXCEPT
SELECT name FROM employees WHERE salary > 9000;

6 UNNEST

UNNEST用于展开数组或JSON数据,使其变为行格式,从而能够更方便地进行查询和分析。在数据库中,存储数组类型的数据时,UNNEST可以帮助我们拆解数组,使得每个元素都能作为单独的行进行查询。

name skills
Alice {SQL, Python}
Bob {Java, C++}
SELECT name, value AS contract_detail
FROM employees,
LATERAL UNNEST(string_to_array(contract::TEXT, ',')) AS contract_data(value);

7 ARRAY_AGG

ARRAY_AGG是聚合函数之一,用于将多个行的值聚合成一个数组。它可以在查询时将相同类别的数据合并到一个数组中,适用于构建JSON结构或优化查询结果的输出格式。

department name
Engineering Alice
Engineering David
SELECT department, ARRAY_AGG(name) AS employees
FROM employees
GROUP BY department;

8 CUBE

CUBE关键字用于创建多维度聚合数据,使得在分组统计时可以同时计算不同组合的数据汇总。它是GROUP BY的扩展,特别适用于报表生成和多层次数据分析。

department salary count
Engineering 8000.00 1
HR 6000.00 1
SELECT department, salary, COUNT(*)
FROM employees
GROUP BY CUBE(department, salary);

9 ROLLUP

ROLLUPGROUP BY类似,但它允许在分组统计的基础上再增加总计行。它能够自动计算分组中的小计和总计数据,在数据分析和报表生成时非常有用。

department salary_total
Engineering 17500.00
HR 6000.00
SELECT department, SUM(salary)
FROM employees
GROUP BY ROLLUP(department);

10 JSON_TABLE

JSON_TABLE用于解析JSON数据,并将其转换为结构化表,使得SQL可以像查询普通表一样查询JSON数据。它适用于处理存储在数据库中的JSON格式数据,并能方便地对其进行筛选、聚合和关联查询。

json_data
{"id": 1, "name": "Alice"}
{"id": 2, "name": "Bob"}
SELECT * FROM JSON_TABLE(
    '[{"id": 1, "name": "Alice"}, {"id": 2, "name": "Bob"}]',
    '$[*]' COLUMNS (
        id INT PATH '$.id',
        name VARCHAR(50) PATH '$.name'
    )
);

 

你可能感兴趣的:(IT知识,mysql,sql,数据库)