XML、数组、图查询(SQL/PGQ)与排序规则

共 47 题
📑 题目列表 47 题
#
★★★

1. PostgreSQL 数组类型,ARRAY[1,2,3]、array_cat、array_append 的函数?

PostgreSQL 数组类型:ARRAY[1,2,3]、array_cat、array_append 的函数是什么?

  • 数组字面量
  • array_cat
  • array_append

PostgreSQL 数组类型支持:ARRAY[1,2,3] 是数组字面量构造;array_cat(a, b) 连接两个数组(如 array_cat(ARRAY[1,2], ARRAY[3]) 返回 {1,2,3});array_append(a, elem) 在数组末尾追加元素(如 array_append(ARRAY[1,2], 3) 返回 {1,2,3});array_prepend(elem, a) 在开头追加。还有 array_remove、array_position、array_length 等。数组操作符 || 也用于连接。数组类型是 PostgreSQL 强大特性。

ARRAY[...] 构造数组,array_cat 连接数组,array_append 追加元素,|| 也可连接。

#
★★★

2. array_agg、array_agg(DISTINCT col)、array_agg(col ORDER BY col) 的差异?

array_agg、array_agg(DISTINCT col)、array_agg(col ORDER BY col) 的差异是什么?

  • array_agg
  • DISTINCT
  • ORDER BY

array_agg(col) 把组内多行聚合成数组(默认无序);array_agg(DISTINCT col) 去重后聚合数组;array_agg(col ORDER BY col) 按指定顺序聚合数组。三者差异:基础 array_agg 无序去重,DISTINCT 去重,ORDER BY 控制顺序。组合:array_agg(DISTINCT col ORDER BY col) 去重并排序。ORDER BY 决定数组元素顺序,DISTINCT 去重。用于组内转数组。

array_agg 按组聚合数组,DISTINCT 去重、ORDER BY 排序,可组合使用。

#
★★★

3. unnest 函数将数组展开为行的用法?

unnest 函数将数组展开为行的用法是什么?

  • unnest
  • 数组转行
  • 用法

unnest(array) 把数组展开为多行(每行一个元素)。例如 unnest(ARRAY[1,2,3]) 返回 3 行。它常用于 FROM 子句(SELECT * FROM unnest(ARRAY[...]) AS t(x))或 SELECT 列表(SELECT unnest(ARRAY[...]))。可多列 unnest 同时展开多个数组。用于把数组扁平化为行,做行展开、连接、分析。

unnest 把数组变多行,用于 FROM 或 SELECT,可多列展开多个数组。

#
★★★

4. 数组的索引(GIN on array)与查询操作符(&&、@>、<@、=any)的语义?

数组的索引(GIN on array)与查询操作符(&&、@>、<@、=any)的语义是什么?

  • GIN array
  • 数组操作符
  • 语义

数组操作符:&& 表示两个数组有交集(共享元素);@> 表示左侧数组包含右侧数组(右侧所有元素都在左侧);<@ 表示左侧数组是右侧数组的子集(包含于);= ANY(array) 表示等于数组中任一元素。数组的 GIN 索引(CREATE INDEX ... USING GIN (col array_ops))可加速 &&、@>、<@ 等操作符。这些用于数组元素过滤与匹配。

&& 交集、@> 包含、<@ 包含于、=ANY 元素匹配。数组 GIN 索引加速这些操作符。

#
★★★

5. JSONB 与数组的建模取舍?

JSONB 与数组的建模取舍是什么?

  • JSONB 建模
  • 数组建模
  • 取舍

JSONB 与数组的建模取舍:数组(如 text[]、int[])适合存储同类型、有序、固定结构的集合,可用 GIN 数组索引做元素匹配,查询高效;JSONB 适合存储结构复杂、嵌套、类型多样的数据,支持路径查询、灵活修改。取舍:简单同质集合、需要元素匹配/去重用数组;复杂嵌套、多变结构用 JSONB。数组更轻量、类型安全,JSONB 更灵活但语义松散。按数据特性选择。

数组适合同质有序集合、元素匹配,JSONB 适合复杂嵌套多变结构。按类型与查询需求取舍。

#
★★★

6. PostgreSQL 中数组元素的可空性?

PostgreSQL 中数组元素的可空性是什么?

  • 数组元素 NULL
  • 多维数组
  • 可空性

PostgreSQL 数组中元素可以是 NULL,数组本身也可以为 NULL。例如 ARRAY[1, NULL, 3] 是合法数组,包含 NULL 元素。数组中的元素为 NULL 与数组本身为 NULL 是不同概念:数组整体为 NULL 表示该列值缺失,元素为 NULL 只是某个位置的值缺失。运行时数组元素可以为 NULL(除非施加了约束)。因此数组元素可空,多数数组操作(unnest 等)会保留 NULL 元素。

数组元素可为 NULL,数组整体也可为 NULL,两者不同。unnest 会保留 NULL 元素。

#
★★★

7. SELECT ARRAY[1,2,3] 的字面量构造?

SELECT ARRAY[1,2,3] 的字面量构造是什么?

  • ARRAY 字面量
  • 构造
  • 类型

SELECT ARRAY[1,2,3] 返回数组字面量 {1,2,3},类型为 integer[]。ARRAY[...] 是数组构造器,元素在括号内用逗号分隔。也可用数组字面量字符串:SELECT '{1,2,3}'::int[]。ARRAY 构造器可嵌套(多维数组)、可混合表达式。SELECT ARRAY[1,2,3] 输出显示为 {1,2,3}。

ARRAY[1,2,3] 构造 integer[] 数组,输出 {1,2,3}。也可用 '{...}'::int[] 字面量。

#
★★★

8. 数组与子查询的转换,ARRAY(SELECT col FROM t)?

数组与子查询的转换:ARRAY(SELECT col FROM t)?

  • ARRAY 子查询
  • 查询转数组
  • 转换

ARRAY(SELECT col FROM t) 把子查询结果(单列多行)转换为数组。例如 ARRAY(SELECT id FROM t WHERE status='a') 把所有符合条件的 id 收集为数组。它把行的集合转成数组,便于作为数组参数传递或与数组操作符配合。子查询必须返回单列。与 array_agg 类似,但 ARRAY(subquery) 独立于 GROUP BY。

ARRAY(subquery) 把单列子查询转数组,类似 array_agg 但独立于分组。

#
★★★

9. 递归 CTE 在图查询中的等价应用?

递归 CTE 在图查询中的等价应用是什么?

  • 递归 CTE 图
  • 图遍历
  • 应用

递归 CTE 可等价实现图查询:锚成员取起始节点,递归成员沿边(连接表)扩展邻居节点,逐层遍历,实现可达性、路径、连通分量等。配合路径数组防环。例如 WITH RECURSIVE reach AS (SELECT start UNION ALL SELECT n FROM reach JOIN edges ON ...) 求可达节点。递归 CTE 实现了关系数据库中基于 SQL 的图遍历,是 SQL/PGQ 出现前的图查询方式。SQL/PGQ 提供了更图化的 MATCH 语法,但递归 CTE 仍可等价实现。

递归 CTE 用锚成员+递归成员沿边遍历实现图可达性/路径查询,是 SQL 中的图查询方式。

#
★★★

10. PostgreSQL 中如何用 ltree 扩展模拟树形结构?

PostgreSQL 中如何用 ltree 扩展模拟树形结构?

  • ltree
  • 树形结构
  • 路径

ltree 扩展提供树形标签路径类型,用于存储分层树结构。用法:CREATE EXTENSION ltree; 列类型 ltree,值如 'Top.Countries.Europe'。常用操作符:@> 表示祖先/后代(path @> subpath 判断祖先关系)、<@ 后代、~ 匹配、? 匹配。ltree 存储带路径的树节点,路径用点分隔,可高效查询祖先/后代、子树。适合组织架构、分类树等。配合 GIST 索引加速。

ltree 用点分隔路径表示树节点,@> 祖先、<@ 后代、~ 匹配,配 GIST 索引,适合树形结构。

#
★★★

11. PostgreSQL 中 Apache AGE 扩展的图查询支持?

PostgreSQL 中 Apache AGE 扩展的图查询支持是什么?

  • Apache AGE
  • 图查询
  • Cypher

Apache AGE 是 PostgreSQL 的图数据库扩展,提供属性图支持,可执行 Cypher 查询(Neo4j 风格)与 SQL 混合。用法:CREATE EXTENSION age; 用 CREATE GRAPH 建图,用 Cypher 语法(MATCH (n)-[r]->(m) RETURN n)查询图数据,数据存储在 PostgreSQL 表中。AGE 把图查询能力嵌入 PostgreSQL,支持图遍历、路径匹配。它是 PostgreSQL 上实现图查询的扩展之一。

Apache AGE 是 PostgreSQL 图扩展,支持 Cypher 语法与 SQL 混合,实现属性图查询。

#
★★★

12. 排序规则(Collation)如何分别影响 ORDER BY 顺序、等值比较与范围扫描?为什么 ci(大小写不敏感)规则下 'A' 与 'a' 相等会让 DISTINCT/GROUP BY 只保留一行?

排序规则(Collation)如何影响 ORDER BY 顺序、等值比较与范围扫描?为什么 ci 规则下 'A' 与 'a' 相等会让 DISTINCT/GROUP BY 只保留一行?

  • Collation 影响
  • ci 规则
  • DISTINCT/GROUP BY

Collation 影响:1) ORDER BY 顺序:按 collation 的排序规则(如大小写、重音、字符权重)排列,如 ci 规则下 'a' 与 'A' 相邻;2) 等值比较:ci 规则下 'A' = 'a' 为真(相等),cs 规则下不等;3) 范围扫描:collation 决定列值在 B-Tree 索引中的顺序,索引必须与 collation 一致才能做范围扫描。ci 规则下 'A' 与 'a' 相等,DISTINCT/GROUP BY 按等值分组,'A' 和 'a' 视为同一组,故只保留一行(去重后合并)。这是 ci collation 下的语义。

Collation 决定排序、等值、范围比较。ci 下 'A'='a',DISTINCT/GROUP BY 按等值分组合并为一行。

#
★★★

13. MySQL 的 utf8mb4_general_ci 与 utf8mb4_0900_ai_ci 在权重规则上有何差异(简化规则 vs 基于 UCA 9.0.0、ai 表示重音不敏感)?为什么 general_ci 对部分字符的比较不符合语言习惯?

MySQL 的 utf8mb4_general_ci 与 utf8mb4_0900_ai_ci 在权重规则上有何差异?为什么 general_ci 对部分字符不符合语言习惯?

  • general_ci
  • 0900_ai_ci
  • UCA

utf8mb4_general_ci 基于简化/粗略的排序规则,多字符相同权重(如一对多字符映射),对部分字符(如特殊字符、重音字符)的比较不完全符合语言习惯;utf8mb4_0900_ai_ci 基于 UCA(Unicode Collation Algorithm)9.0.0,ai 表示 accent-insensitive(重音不敏感),权重更精确、更符合 Unicode 语言习惯。差异:general_ci 简化规则,某些字符(如 ß、å 等)比较可能不符合期望;0900_ai_ci 遵循 UCA,重音不敏感、权重更合理。推荐用 0900_ai_ci(MySQL 8 默认)。

general_ci 简化权重、不符合部分语言习惯;0900_ai_ci 基于 UCA 9.0.0、ai 重音不敏感、更符合语言习惯。

#
★★★

14. 列级、表达式级(COLLATE 子句)与数据库级排序规则的优先级如何裁决?JOIN 或 UNION 两侧 collation 冲突时报 Illegal mix of collations 应如何解决?

列级、表达式级(COLLATE 子句)与数据库级排序规则的优先级如何裁决?JOIN/UNION 两侧 collation 冲突时报 Illegal mix of collations 应如何解决?

  • collation 优先级
  • 冲突
  • 解决

Collation 优先级:表达式级(COLLATE 子句)> 列级(列定义)> 表级 > 数据库级(默认)。COLLATE 子句显式指定的最高优先级。当 JOIN 或 UNION 两侧列 collation 不一致(如 utf8mb4_general_ci 与 utf8mb4_bin)时,MySQL 报 "Illegal mix of collations" 错误。解决:1) 在比较/连接中用 COLLATE 显式指定一侧 collation(如 JOIN ... ON a COLLATE utf8mb4_bin = b);2) 统一列 collation(ALTER TABLE 修改);3) 用 CONVERT 转换字符集。最简单是显式 COLLATE 统一。

优先级:COLLATE 子句 > 列 > 表 > 数据库。冲突时用显式 COLLATE 或统一列 collation 解决。

#
★★★

15. PostgreSQL 为什么要跟踪 ICU collation 版本(pg_database_collation_actual_version、ALTER COLLATION ... REFRESH VERSION)?glibc/ICU 升级后不刷新会给 B-Tree 索引正确性带来什么风险?

PostgreSQL 为什么要跟踪 ICU collation 版本?glibc/ICU 升级后不刷新会给 B-Tree 索引正确性带来什么风险?

  • ICU collation 版本
  • REFRESH VERSION
  • 索引正确性

PostgreSQL 跟踪 ICU collation 版本(pg_database_collation_actual_version、ALTER COLLATION ... REFRESH VERSION)是因为 collation 的排序规则由底层 ICU/glibc 库决定。若系统升级 ICU/glibc 导致 collation 排序规则变化,但索引仍是旧版本的顺序,会出现索引与数据不一致:B-Tree 索引按旧 collation 顺序排列,而查询按新 collation 比较,导致索引扫描遗漏/错误(正确性风险)。通过跟踪版本并 ALTER COLLATION ... REFRESH VERSION 可检测并重建索引。不刷新则索引可能失效或返回错误结果。

ICU/glibc 升级改变 collation 排序,若索引未重建,B-Tree 顺序与比较不一致,导致索引错误。需 REFRESH VERSION 并重建索引。

#
★★★

16. 为什么默认 collation 下的 B-Tree 索引不能加速 LIKE 'abc%'?text_pattern_ops 索引或 C/POSIX collation 列如何解决前缀匹配走索引?

为什么默认 collation 下的 B-Tree 索引不能加速 LIKE 'abc%'?text_pattern_ops 或 C/POSIX collation 如何解决?

  • collation 与索引
  • text_pattern_ops
  • 前缀匹配

默认 collation(如 ICU/非默认)的 B-Tree 索引不能直接加速 LIKE 'abc%',因为 LIKE 的前缀匹配需要按字节/二进制前缀顺序,而默认 collation 按语言规则排序(大小写、重音、权重),索引顺序与 LIKE 前缀匹配所需顺序不一致,优化器无法用索引做前缀范围扫描。解决:1) 用 text_pattern_ops 操作符类建索引(使索引按字节/模式顺序,适合 LIKE 前缀匹配);2) 用 C/POSIX collation 的列(二进制排序,前缀匹配可用索引)。text_pattern_ops 让索引按文本模式顺序,支持 LIKE 前缀。

默认 collation 语言排序与 LIKE 前缀字节顺序不一致,索引无法用。text_pattern_ops 或 C/POSIX collation 使索引按字节顺序支持前缀匹配。

#
★★★

17. 二进制排序(utf8mb4_bin、C/POSIX)与语言学排序在比较结果、索引顺序与性能上的本质差异是什么?为什么二进制排序最快但顺序“不自然”?

二进制排序(utf8mb4_bin、C/POSIX)与语言学排序在比较结果、索引顺序与性能上的本质差异是什么?为什么二进制排序最快但顺序"不自然"?

  • 二进制排序
  • 语言学排序
  • 性能

二进制排序(utf8mb4_bin、C/POSIX)按字符字节码/代码点直接比较,结果确定、索引顺序与字节一致、性能最快(无权重计算);语言学排序按语言规则(大小写、重音、字符权重)比较,结果符合语言习惯,但需计算权重、性能较慢。本质差异:二进制按字节码序,语言学按 Unicode 权重表。二进制排序最快但顺序"不自然":因为 'A' 与 'a' 按 ASCII 码分开排列('A' 65 < 'a' 97),大小写不归组,重音字符也不相邻,不符合人类语言习惯。

二进制按字节码比较、快、顺序不自然(大小写/重音不归组);语言学按权重、符合语言习惯但慢。

#
★★★

18. PostgreSQL 的 citext 扩展与“COLLATE + LOWER() 表达式索引”实现大小写不敏感查询时,在实现原理、可组合性与性能上有何差异?

PostgreSQL 的 citext 扩展与"COLLATE + LOWER() 表达式索引"实现大小写不敏感查询时,在实现原理、可组合性与性能上有何差异?

  • citext
  • LOWER() 表达式索引
  • 差异

citext 扩展提供大小写不敏感文本类型,比较时自动忽略大小写、无需改查询;LOWER() 表达式索引(CREATE INDEX ON t (LOWER(col)) + WHERE LOWER(col) = ...)通过表达式索引实现大小写不敏感查询。差异:citext 从类型层面忽略大小写,所有比较自动不敏感,但需改列类型、可能影响排序与索引兼容性;LOWER() 表达式索引需在查询中显式写 LOWER(col),可组合性差(需保持表达式一致),但更灵活、性能可控。citext 简单但隐性,表达式索引显式但需一致写法。

citext 类型层自动忽略大小写(简单),LOWER() 表达式索引需显式 LOWER(col)(可组合性差但灵活)。两者实现路径不同。

#
★★★

19. MySQL 中 utf8mb3 与 utf8mb4 表关联时,为什么隐式字符集/排序规则转换可能导致索引失效?如何在 EXPLAIN 中识别 using where; Using temporary 与 convert()?

MySQL 中 utf8mb3 与 utf8mb4 表关联时,为什么隐式字符集/排序规则转换可能导致索引失效?如何在 EXPLAIN 中识别?

  • 字符集转换
  • 索引失效
  • EXPLAIN 识别

utf8mb3 与 utf8mb4 表关联时,MySQL 会隐式把 utf8mb3 列转换为 utf8mb4 进行比较(因为 utf8mb4 是超集)。隐式转换后,对比列被包上转换函数(convert()),导致该列无法使用其索引(索引基于原列值,转换后值不同),从而索引失效。EXPLAIN 中识别:extra 列出现 "Using where; Using temporary; Using filesort" 等,或列上出现 convert() 隐式转换(可看 Using where 中有转换)。解决:统一两侧字符集/collation,或用显式 CONVERT 到一致。

utf8mb3 隐式转 utf8mb4 使列被转换、索引失效。EXPLAIN 见 Using where/Using temporary/convert() 等迹象。

#
★★

20. 什么是非确定性排序规则(nondeterministic collation,PostgreSQL 12+)?它对 LIKE、模式匹配与索引使用有哪些限制?

什么是非确定性排序规则(nondeterministic collation,PostgreSQL 12+)?它对 LIKE、模式匹配与索引使用有哪些限制?

  • 非确定性 collation
  • LIKE 限制
  • 索引限制

非确定性排序规则(nondeterministic collation,PostgreSQL 12+)指排序比较结果不保证可复现的确定性,如大小写不敏感、重音不敏感等由 ICU 提供的 collation。限制:非确定性 collation 下,LIKE/模式匹配(依赖按字符顺序扫描)可能无法正确使用,且不能用于某些索引(如 B-Tree 索引需要确定性排序,非确定性 collation 的列建索引可能受限或被禁止);范围扫描、前缀匹配等也受影响。PostgreSQL 对非确定性 collation 的索引与模式匹配有限制。

非确定性 collation 大小写/重音不敏感,但 LIKE/模式匹配与 B-Tree 索引受限(索引需确定性排序)。

#
★★

21. SQL Server 的 PIVOT(如 SUM(amount) FOR quarter IN ([Q1],[Q2],[Q3],[Q4]))如何工作?它对聚合函数单一性与 IN 列必须静态列出有哪些限制?

SQL Server 的 PIVOT 如何工作?它对聚合函数单一性与 IN 列必须静态列出有哪些限制?

  • PIVOT
  • 聚合单一
  • 静态 IN

SQL Server 的 PIVOT 把行转列:PIVOT (聚合函数(列) FOR 待转列 IN ([值1],[值2],...))。例如 PIVOT (SUM(amount) FOR quarter IN ([Q1],[Q2],[Q3],[Q4])) 把 quarter 列的值(Q1-Q4)转为 4 列,每列是该季度 amount 的 SUM。限制:1) PIVOT 只能指定一个聚合函数(不能多个);2) IN 列表必须静态列出所有列名(不能动态、不能子查询),行转列时列是固定的;3) 聚合函数作用于指定列。这些限制使 PIVOT 适合已知固定列数的场景。

PIVOT 用单聚合函数 FOR 列 IN (静态值列表) 行转列。限制:单聚合、IN 列必须静态。

#
★★

22. 如何用条件聚合(SUM(CASE WHEN quarter='Q1' THEN amount END) + GROUP BY)实现与 PIVOT 等价的行转列?为什么这是跨数据库最可移植的方案?

如何用条件聚合(SUM(CASE WHEN ... THEN ... END) + GROUP BY)实现与 PIVOT 等价的行转列?为什么这是跨数据库最可移植的方案?

  • 条件聚合
  • 行转列
  • 可移植

条件聚合行转列:SELECT ..., SUM(CASE WHEN quarter='Q1' THEN amount END) AS q1, SUM(CASE WHEN quarter='Q2' THEN amount END) AS q2 FROM t GROUP BY ...。每个目标列用一个 CASE WHEN 条件聚合,把对应值的行求和,GROUP BY 其余列。这是跨数据库最可移植的方案,因为 CASE WHEN 是 SQL 标准语法,所有数据库都支持(PostgreSQL、MySQL、Oracle、SQL Server 都支持),而 PIVOT 是特定数据库语法。因此条件聚合可移植性最好,是跨库行转列的标准方案。

条件聚合用 CASE WHEN + SUM + GROUP BY 行转列,因 CASE 是标准语法,跨数据库最可移植。

#
★★

23. PostgreSQL tablefunc 扩展的 crosstab(sql, categories_sql) 如何行转列?为什么必须用 AS (row_name text, q1 int, ...) 预先声明输出结构?

PostgreSQL tablefunc 扩展的 crosstab(sql, categories_sql) 如何行转列?为什么必须用 AS 预先声明输出结构?

  • crosstab
  • 输出结构
  • 声明

tablefunc 扩展的 crosstab(sql, categories_sql) 做行转列,其中 sql 返回 (row_name, category, value) 三列,categories_sql 返回转成列的类别列表。crosstab 把 category 值转为列,value 填充。必须用 AS (row_name text, q1 int, ...) 预先声明输出结构,因为 crosstab 是表函数,PostgreSQL 无法自动推断输出列(列数、列名、类型由 SQL 动态决定),必须静态声明返回列。这是 crosstab 的使用要求。

crosstab 需源 SQL 返回 row_name/category/value 三列,且必须 AS 声明输出列结构(列数/类型不能自动推断)。

#
★★

24. 列转行(UNPIVOT)在 SQL Server/Oracle(UNPIVOT 子句)与 PostgreSQL(LATERAL + VALUES 或 unnest)中分别如何实现?

列转行(UNPIVOT)在 SQL Server/Oracle(UNPIVOT 子句)与 PostgreSQL(LATERAL + VALUES 或 unnest)中分别如何实现?

  • UNPIVOT
  • LATERAL VALUES
  • 列转行

列转行实现:SQL Server/Oracle 用 UNPIVOT 子句:SELECT ... FROM t UNPIVOT (value FOR col IN (q1, q2, q3)) 把宽表的多列转为行(key/value 两列)。PostgreSQL 无 UNPIVOT,用 LATERAL + VALUES 或 unnest:SELECT ... FROM t, LATERAL (VALUES ('q1', q1), ('q2', q2), ('q3', q3)) AS u(col, value),或 unnest(ARRAY['q1','q2','q3'], ARRAY[q1,q2,q3])。两者都实现列转行,PostgreSQL 用 LATERAL/VALUES 更通用。

SQL Server/Oracle 用 UNPIVOT 子句,PostgreSQL 用 LATERAL + VALUES 或 unnest 实现列转行。

#
★★

25. 列数动态未知时,行转列有哪些方案(拼接动态 SQL vs 聚合为 JSON/数组输出)?二者在类型安全与客户端处理上的取舍是什么?

列数动态未知时,行转列有哪些方案(拼接动态 SQL vs 聚合为 JSON/数组输出)?二者在类型安全与客户端处理上的取舍是什么?

  • 动态 SQL
  • JSON/数组输出
  • 类型安全

列数动态未知时行转列方案:1) 拼接动态 SQL:先查出不重复的列值,拼成动态 SQL(PIVOT/crosstab 的 IN 列表),执行返回动态列。类型安全差(列名/类型运行时确定),客户端需处理动态列名,但结果符合传统表结构;2) 聚合为 JSON/数组输出:用 json_object_agg/array_agg 把动态列聚合为 JSON 对象或数组,列数不限。类型安全较好(JSON 保持类型),客户端直接解析 JSON 更灵活。取舍:动态 SQL 适合下游需要固定列的分析,JSON 适合灵活/前端消费。

动态列行转列:动态 SQL(列名运行时确定、类型安全差)或 JSON/数组聚合(类型安全、灵活)。按客户端需求取舍。

#
★★

26. UNPIVOT 默认会丢弃值为 NULL 的行,INCLUDE NULLS 与 EXCLUDE NULLS 的语义差异是什么?用 LATERAL VALUES 模拟时如何保留 NULL?

UNPIVOT 默认会丢弃值为 NULL 的行,INCLUDE NULLS 与 EXCLUDE NULLS 的语义差异是什么?用 LATERAL VALUES 模拟时如何保留 NULL?

  • UNPIVOT NULL
  • INCLUDE/EXCLUDE NULLS
  • LATERAL 保留 NULL

UNPIVOT 默认(EXCLUDE NULLS)会丢弃值为 NULL 的行(因为 NULL 值对应的转行无意义)。INCLUDE NULLS 则保留这些行(即使值为 NULL 也输出一行)。差异:EXCLUDE NULLS 跳过 NULL 值的行,INCLUDE NULLS 保留。用 LATERAL VALUES 模拟时,VALUES 会保留 NULL(VALUES ('q1', q1) 中 q1 为 NULL 也会生成 ('q1', NULL) 行),因此 LATERAL VALUES 天然保留 NULL;若需排除 NULL,可用 WHERE value IS NOT NULL。

UNPIVOT 默认丢弃 NULL 行,INCLUDE NULLS 保留。LATERAL VALUES 天然保留 NULL,排除需 WHERE value IS NOT NULL。

#
★★

27. 如何用 FILTER (WHERE ...) + GROUP BY 或 JSON_OBJECTAGG/JSONB_OBJECT_AGG 实现行转列聚合?与固定列 PIVOT 在结果形态上有何不同?

如何用 FILTER (WHERE ...) + GROUP BY 或 JSON_OBJECTAGG/JSONB_OBJECT_AGG 实现行转列聚合?与固定列 PIVOT 在结果形态上有何不同?

  • FILTER 聚合
  • JSON_OBJECTAGG
  • 结果形态

行转列聚合:FILTER + GROUP BY:SELECT ..., SUM(x) FILTER (WHERE quarter='Q1') AS q1, SUM(x) FILTER (WHERE quarter='Q2') AS q2 FROM t GROUP BY ...(每个目标列一个 FILTER 条件聚合);JSONB_OBJECT_AGG:SELECT ..., jsonb_object_agg(quarter, amount) FROM t GROUP BY ... 把动态季度聚合为 JSON 对象。区别:FILTER 固定列形态(每列一个对象,列固定);JSON_OBJECTAGG 把行转成 JSON 对象(键值对,列不固定)。FILTER 结果是有固定列的表,JSON_OBJECTAGG 是单列 JSON 对象。

FILTER 条件聚合生成固定列表,JSON_OBJECTAGG 生成 JSON 对象(键值对)。两者结果形态不同(固定列 vs JSON 对象)。

#
★★

28. crosstab 对源 SQL 的输出顺序(row_name, category, value)有什么要求?某行缺少某个 category 时结果如何填充?

crosstab 对源 SQL 的输出顺序(row_name, category, value)有什么要求?某行缺少某个 category 时结果如何填充?

  • crosstab 顺序
  • 缺失 category
  • 填充

crosstab 的源 SQL 必须返回三列:row_name(行标识)、category(类别,转成列)、value(填充值),且必须按 row_name 排序(同一 row 的 category 连续)。某行缺少某个 category 时,crosstab 会填充 NULL(该 category 列对应值为 NULL),因为转列时该 row 没有该 category 的值。crosstab 要求源 SQL 按 row_name 排序,否则结果错误。

crosstab 源 SQL 返回 row_name/category/value 且按 row_name 排序,缺失 category 填充 NULL。

#
★★

29. Oracle 的 PIVOT XML 如何通过 ANY 支持动态列名?普通 PIVOT 的 IN 列表为什么不允许使用表达式或子查询?

Oracle 的 PIVOT XML 如何通过 ANY 支持动态列名?普通 PIVOT 的 IN 列表为什么不允许使用表达式或子查询?

  • PIVOT XML
  • ANY 动态
  • IN 列表限制

Oracle 的 PIVOT XML 通过 ANY 支持动态列名:PIVOT XML (SUM(amount) FOR quarter IN (SELECT DISTINCT quarter FROM t)) 或 PIVOT XML ... IN (ANY),把结果输出为 XML(列名动态,作为 XML 形式)。普通 PIVOT 的 IN 列表必须静态列出具体值(如 [Q1],[Q2]),因为转列后列名必须固定(列结构在编译时确定),不允许表达式或子查询(动态产生列名无法在编译期固定列结构)。PIVOT XML 用 ANY 或子查询支持动态列,输出 XML。

普通 PIVOT IN 列表必须静态(列名编译期固定),PIVOT XML 用 ANY/子查询支持动态列并输出 XML。

#
★★

30. 多维数组的支持,matrix[[1,2],[3,4]] 的访问与限制?

多维数组的支持:matrix[[1,2],[3,4]] 的访问与限制是什么?

  • 多维数组
  • 构造
  • 访问

PostgreSQL 支持多维数组:matrix[[1,2],[3,4]] 构造 2x2 二维数组,用两个下标访问(如 matrix[1][2] 返回 2,下标从 1 开始)。维度由 array_ndims 判断,array_length 可查各维长度。限制:多维数组的所有维度必须规则(每行元素数相同,不能是锯齿数组);数组类型不能含维度不匹配;升维/降维需注意。多维数组用于矩阵、网格数据。

matrix[[1,2],[3,4]] 构造二维数组,用 matrix[1][2] 访问,维度需规则(不能锯齿)。

#
★★

31. ANY(array) 与 ALL(array) 的用法?

ANY(array) 与 ALL(array) 的用法是什么?

  • ANY(array)
  • ALL(array)
  • 用法

x = ANY(array) 表示 x 等于数组中任一元素;x = ALL(array) 表示 x 等于数组中所有元素(即所有元素都等于 x)。用于比较操作符:x > ANY(array) 表示 x 大于数组中任一元素(大于最小),x > ALL(array) 表示 x 大于所有元素(大于最大)。ANY/ALL 可与数组或子查询(=ANY(subquery))配合。用法:ANY 用于"存在一个满足",ALL 用于"全部满足"。

ANY 存在一个满足、ALL 全部满足。x > ANY 大于最小、x > ALL 大于最大。可配数组或子查询。

#
★★

32. array_length 与 array_dims 的差异?

array_length 与 array_dims 的差异是什么?

  • array_length
  • array_dims
  • 差异

array_length(array, dim) 返回指定维度的长度(整数),如 array_length(ARRAY[1,2,3], 1) 返回 3;array_dims(array) 返回各维度的边界描述字符串(如 '[1:3]' 或 '[1:2][1:3]')。差异:array_length 返回整数长度(指定维度),array_dims 返回维度边界字符串(可含多维)。array_ndims 返回维度数。array_length 用于程序化取长度,array_dims 用于查看维度边界。

array_length 返回指定维度整数长度,array_dims 返回维度边界字符串(如 [1:3])。

#
★★

33. array_to_string 的分隔符参数?

array_to_string 的分隔符参数是什么?

  • array_to_string
  • 分隔符
  • 用法

array_to_string(array, delimiter) 把数组元素用分隔符连接成字符串。例如 array_to_string(ARRAY['a','b','c'], ',') 返回 'a,b,c'。若元素为 NULL,默认跳过(NULL 元素不输出、不占分隔符),可用第三个参数 NULL 替换(array_to_string(array, delimiter, null_string) 把 NULL 元素替换为指定字符串)。delimiter 是分隔符参数,用于连接数组元素。

array_to_string(array, delimiter) 用分隔符连接数组元素,NULL 元素默认跳过,可指定 null_string 替换。

#
★★

34. unnest 在 FROM 子句中的使用(LATERAL 隐式)?

unnest 在 FROM 子句中的使用(LATERAL 隐式)是什么?

  • unnest FROM
  • LATERAL 隐式
  • 用法

unnest 在 FROM 子句中使用:SELECT * FROM unnest(ARRAY[1,2,3]) AS t(x)。表函数在 FROM 中隐式 LATERAL(可引用前面的列)。例如 SELECT a, x FROM t, unnest(t.arr) AS u(x) 展开每个行的数组列。unnest 作为表函数返回多行,配合其他表列展开。隐式 LATERAL 使 unnest 可引用左侧列。常用于数组列展开。

unnest 在 FROM 中作表函数,隐式 LATERAL 可引用左侧列,用于展开数组列。

#
★★

35. GRAPH_TABLE、MATCH 子句、路径模式(-/-、-/-/->)的语法?

GRAPH_TABLE、MATCH 子句、路径模式(-/-、-/-/->)的语法是什么?

  • GRAPH_TABLE
  • MATCH
  • 路径模式

SQL/PGQ(SQL:2023)的图查询:GRAPH_TABLE 在 FROM 中引用属性图,MATCH 子句定义路径模式。路径模式语法:节点(n)、边([r])、- 表示无向边、-> 表示有向边、-/- 表示无向路径、-/-/-> 表示有向路径。例如 MATCH (n:Person)-[r:KNOWS]->(m:Person) 表示从 Person 节点 n 经 KNOWS 边到 Person 节点 m。GRAPH_TABLE ... MATCH ... 返回路径匹配的行。归一化:-/- 连接任意方向,-/-/-> 有向。

GRAPH_TABLE 引用图,MATCH 定义路径模式,- 无向边、-> 有向边、-/- 无向路径、-/-/-> 有向路径。

#
★★

36. SQL/PGQ 的属性图(Property Graph)定义(CREATE PROPERTY GRAPH)?

SQL/PGQ 的属性图(Property Graph)定义(CREATE PROPERTY GRAPH)是什么?

  • CREATE PROPERTY GRAPH
  • 属性图
  • 定义

SQL/PGQ 用 CREATE PROPERTY GRAPH 定义属性图:CREATE PROPERTY GRAPH graph_name VERTEX TABLES (table1 LABEL l1, table2 LABEL l2) EDGE TABLES (edge_table LABEL e1 SOURCE KEY (fk) REFERENCES table1 DESTINATION KEY (id) REFERENCES table1)。属性图把关系表映射为顶点(VERTEX TABLES)和边(EDGE TABLES),顶点表有标签(LABEL),边表有 SOURCE/DESTINATION 键。定义后可用 GRAPH_TABLE/MATCH 查询。

CREATE PROPERTY GRAPH 定义属性图,VERTEX TABLES 顶点表、EDGE TABLES 边表(含 SOURCE/DESTINATION 键)。

#
★★

37. 图查询与图数据库(Neo4j、TigerGraph)的取舍,哪些图计算适合 SQL?

图查询与图数据库(Neo4j、TigerGraph)的取舍:哪些图计算适合 SQL?

  • 图查询 SQL
  • 图数据库
  • 取舍

图查询与图数据库取舍:SQL/PGQ 适合简单图遍历、路径、关系查询,依赖关系数据库,适合与关系数据混合、事务性、中小规模图;图数据库(Neo4j、TigerGraph)适合大规模复杂图计算(多跳遍历、图算法如最短路径、社区发现、PageRank)、高并发图查询。适合 SQL 的图计算:简单路径、邻接查询、层级关系、有限深度的遍历;复杂图算法、大规模图分析用图数据库。取舍:数据规模、图复杂度、是否需图算法。

SQL 适合简单路径/邻接/有限遍历,图数据库适合大规模复杂图算法。按规模与复杂度取舍。

#

38. XML 数据类型在 PostgreSQL、SQL Server、Oracle 中的支持差异?

XML 数据类型在 PostgreSQL、SQL Server、Oracle 中的支持差异是什么?

  • XML 类型
  • 支持差异
  • 函数

XML 数据类型支持差异:PostgreSQL 有 xml 类型,支持 XML 存储、xpath 函数、XMLTABLE 的部分支持;SQL Server 有 xml 类型,支持 XQuery、XMLQUERY、XMLNODES、XPath 查询,功能强大;Oracle 有 XMLType,支持 XMLTABLE、XPath、XML 函数,功能最丰富。差异主要在功能:Oracle/SQL Server 的 XML 功能更完整(XQuery、XMLTABLE 完整),PostgreSQL 的 XML 支持较基础(xpath、XMLTABLE 有限)。XML 存储与解析性能也因实现而异。

Oracle/SQL Server XML 功能完整(XQuery/XMLTABLE),PostgreSQL XML 支持较基础(xpath 等)。

#

39. XMLTABLE 函数(SQL:2003)将 XML 转为关系行的用法?

XMLTABLE 函数(SQL:2003)将 XML 转为关系行的用法是什么?

  • XMLTABLE
  • XML 转行
  • 用法

XMLTABLE 把 XML 文档按 XPath 表达式展开为关系行。用法:XMLTABLE(xpath_expr PASSING xml_col COLUMNS (col1 type PATH '...', col2 type PATH '...'))。它从 xml 中按 XPath 定位节点,把每个匹配节点转成一行,COLUMNS 定义输出列(用 PATH 提取)。XMLTABLE 是 SQL:2003 标准,Oracle/SQL Server 支持,PostgreSQL 也支持(部分)。用于 XML 数据转关系表查询。

XMLTABLE 用 XPath 定位节点、COLUMNS 定义列,把 XML 转成关系行。

#

40. XPath 查询在 PostgreSQL(xpath 函数)中的语法?

XPath 查询在 PostgreSQL(xpath 函数)中的语法是什么?

  • xpath 函数
  • 语法
  • XPath

PostgreSQL 的 xpath(xpath_expr, xml [, namespaces]) 返回数组,按 XPath 表达式从 XML 中取值。例如 xpath('/book/title/text()', xml_data) 返回匹配的文本节点数组。xpath 返回 xml 数组。可选 namespaces 参数定义命名空间(XMLNAMESPACES)。xpath 是 PostgreSQL 的 XML 查询函数,用于提取 XML 节点。查询结果需转 text 或适当处理。

xpath(xpath_expr, xml, namespaces) 按 XPath 提取节点返回 xml 数组。

#

41. XMLNAMESPACES 子句的用法?

XMLNAMESPACES 子句的用法是什么?

  • XMLNAMESPACES
  • 命名空间
  • 用法

XMLNAMESPACES 子句用于声明 XML 命名空间,供 XPath/XMLTABLE 使用。用法:XMLNAMESPACES(DEFAULT 'uri', 'prefix' AS 'uri'),在 XMLTABLE 或 xpath 函数中传给命名空间。它把 URI 映射到前缀,使 XPath 能引用带命名空间的节点。例如 XMLTABLE(XMLNAMESPACES('http://x' AS ns), '/ns:root/ns:item' ...)。XMLNAMESPACES 解决 XML 命名空间解析问题。

XMLNAMESPACES 声明命名空间(prefix 映射 URI),供 XPath/XMLTABLE 引用带命名空间的节点。

#

42. 图遍历的最短路径算法在 SQL 中的实现?

图遍历的最短路径算法在 SQL 中的实现是什么?

  • 最短路径
  • BFS
  • 递归 CTE

图遍历最短路径在 SQL 中通常用递归 CTE 实现 BFS(广度优先搜索):锚成员取起始节点,递归成员沿边扩展,记录路径与深度,第一次到达目标节点即最短路径(BFS 保证最短路)。用 UNION ALL 逐层扩展,配合路径数组去重,找到目标节点时记录深度。也可用 SQL/PGQ 的图查询(若支持)。最短路径在 SQL 中实现为 BFS 递归 CTE,适合中小规模图。

最短路径用递归 CTE 做 BFS 逐层扩展,记录路径与深度,BFS 首次到达即最短路。

#

43. MATCH (n:Person)-[r:KNOWS]->(m:Person) 在 SQL/PGQ 中的翻译?

MATCH (n:Person)-[r:KNOWS]->(m:Person) 在 SQL/PGQ 中的翻译是什么?

  • Cypher 匹配
  • SQL/PGQ 翻译
  • 图模式

MATCH (n:Person)-[r:KNOWS]->(m:Person) 是 Cypher 语法(Neo4j),在 SQL/PGQ 中翻译为 SQL 的 GRAPH_TABLE + MATCH 子句:SELECT ... FROM GRAPH_TABLE (graph_name MATCH (n:Person)-[r:KNOWS]->(m:Person) COLUMNS (n.id AS n_id, m.id AS m_id))。即把 Cypher 的 MATCH 路径模式放进 SQL/PGQ 的 GRAPH_TABLE MATCH 子句,节点/边标签用 : 表示,路径用 -> 表示有向。SQL/PGQ 用 SQL 语法封装图模式匹配。

Cypher 的 MATCH (n:Person)-[r:KNOWS]->(m:Person) 在 SQL/PGQ 中转入 GRAPH_TABLE MATCH 子句。

#

44. SQL/PGQ 与 GQL(Graph Query Language)的标准化关系?

SQL/PGQ 与 GQL(Graph Query Language)的标准化关系是什么?

  • SQL/PGQ
  • GQL
  • 关系

SQL/PGQ 与 GQL 都是 ISO 标准化的图查询语言,关系:SQL/PGQ(SQL Property Graph Queries,SQL:2023 的一部分)把属性图查询嵌入 SQL,是 SQL 标准的扩展,在 SQL 内用 GRAPH_TABLE/MATCH 查询图;GQL(Graph Query Language)是独立的图查询语言标准(ISO/IEC 39075),用于图数据库(如 Neo4j 的 Cypher 是 GQL 前身)。两者共享属性图概念(节点、边、标签、路径),SQL/PGQ 面向 SQL 内嵌图查询,GQL 是独立图语言。SQL/PGQ 与 GQL 兼容于属性图模型。

SQL/PGQ 是 SQL 标准内嵌图查询,GQL 是独立图查询语言标准,两者都基于属性图模型。

#

45. ltree 的路径查询操作符(~、?、@)的语义?

ltree 的路径查询操作符(~、?、@)的语义是什么?

  • ltree 操作符
  • ~ 匹配
  • ? 匹配

ltree 路径查询操作符:path ~ lquery 表示路径匹配 lquery 模式(类似正则,如 'Top.*' 匹配以 Top 开头的路径);path ? lquery 与 path ~ lquery 等价(都是 lquery 匹配操作符);path @ ltxtquery / path ~ ltxtquery 表示与 ltxtquery(全文式查询)匹配。@> 表示祖先(path @> subpath),<@ 表示后代。ltree 的操作符用于树路径的模式匹配与祖先/后代判断。

ltree 的 ~ 与 ? 匹配 lquery、@ 与 ~ 匹配 ltxtquery,@> 祖先、<@ 后代。用于树路径查询。

#

46. SQL/PGQ(Property Graph Queries,SQL:2023)的核心概念,节点、边、路径模式?

SQL/PGQ(Property Graph Queries,SQL:2023)的核心概念:节点、边、路径模式是什么?

  • SQL/PGQ 概念
  • 节点/边
  • 路径模式

SQL/PGQ(SQL:2023 的属性图查询)核心概念:节点(Vertex,有标签 Label 和属性 Property)、边(Edge,有源/目标节点、标签、属性)、路径模式(Path Pattern,用节点和边的序列描述遍历,如 (n)-[r]->(m),支持可变长度、方向)。查询用 GRAPH_TABLE + MATCH 定义路径模式,返回匹配的节点/边。SQL/PGQ 把属性图(规则)纳入 SQL 标准,实现图查询。

SQL/PGQ 核心概念:节点(标签+属性)、边(源/目标+标签)、路径模式(GRAPH_TABLE MATCH 定义遍历)。

#

47. 图数据库 vs 关系数据库的选型依据?

图数据库 vs 关系数据库的选型依据是什么?

  • 图数据库
  • 关系数据库
  • 选型

图数据库 vs 关系数据库选型依据:图数据库适合数据关系密集(多跳、复杂关联)、图遍历/图算法(社交网络、推荐、路径)、关系结构动态变化,查询以图遍历为主;关系数据库适合结构化数据、事务性强、统计/聚合/报表、关系相对固定、需要强约束与 SQL 生态。选型:数据关系是否复杂、查询是否需要多跳遍历、是否需要图算法、事务与 ACID 要求、团队 SQL 能力。图密集用图库,关系/事务用关系库。

图数据库适合复杂关系/多跳遍历/图算法,关系数据库适合结构化/事务/聚合报表。按关系复杂度与查询类型选型。