SQL 聚合与处理

SQL 聚合与处理 (★★★)

#open-sql #database

聚合函数

函数 返回值 说明
COUNT(*) 行数 计算所有行,包括 NULL
COUNT(DISTINCT col) 不同值的数量 排除重复和 NULL
SUM(col) 值的总和 仅数值列
AVG(col) 平均值 仅数值列
MAX(col) 最大值 适用于任何可比较类型
MIN(col) 最小值 适用于任何可比较类型
📌聚合函数忽略 NULL 值(COUNT(*) 除外)。如果所有值都是 NULL,SUMAVG 返回 NULL。
1
2
3
4
5
6
7
8
9
10
11
12
" 计算行数
SELECT COUNT(*) INTO lv_count FROM sflight WHERE carrid = 'LH'.

" 多个聚合
SELECT carrid,
COUNT(*) AS cnt,
SUM(price) AS total,
AVG(price) AS avg_price,
MAX(price) AS highest
INTO TABLE lt_summary
FROM sflight
GROUP BY carrid.

GROUP BY

  • 将共享列值的行分组
  • SELECT 中每个非聚合列必须出现在 GROUP BY 中
  • 在 SELECT 列表之前评估
1
2
3
4
SELECT carrid, connid, COUNT(*) AS cnt
INTO TABLE lt_counts
FROM sflight
GROUP BY carrid, connid.
⚠️如果你选择了不在 GROUP BY 中且未聚合的列,结果未定义且取决于数据库。

HAVING

  • 过滤(不是单个行)
  • 在 GROUP BY 之后、SELECT 之前应用
  • 条件中可使用聚合函数
1
2
3
4
5
SELECT carrid, COUNT(*) AS cnt
INTO TABLE lt_result
FROM sflight
GROUP BY carrid
HAVING COUNT(*) > 10. " 仅行数 > 10 的组
子句 过滤对象 应用时机
WHERE 单个行 分组之前
HAVING 分组之后

ORDER BY

语法 行为
ORDER BY col1 col2 按指定列排序
ORDER BY 1 3 按列位置排序(从 1 开始)
ORDER BY col1 ASCENDING col2 DESCENDING 显式方向
1
2
3
4
SELECT carrid, price
INTO TABLE lt_sorted
FROM sflight
ORDER BY carrid ASCENDING price DESCENDING.
💡ORDER BY 绕过 SAP 表缓冲。对于缓冲表的排序输出,改为在 ABAP 中对内表排序。

DISTINCT

  • 从结果集中删除重复行
  • 应用于整行,而非单个列
1
2
3
4
" 唯一城市对
SELECT DISTINCT cityfrom, cityto
INTO TABLE lt_routes
FROM spfli.
⚠️DISTINCT 应用于完整的结果行。它不与单个聚合列表达式组合(COUNT(DISTINCT col) 除外)。

SELECT 处理方式

方式 语法 使用场景
一次性 SELECT ... INTO TABLE itab 中小型结果集
循环 SELECT ... ENDSELECT 逐行处理
分包 SELECT ... PACKAGE SIZE n ... ENDSELECT 大数据量分块
游标 OPEN CURSOR ... FETCH ... CLOSE CURSOR 精细控制

基于游标的处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
DATA: lv_cursor TYPE cursor.

OPEN CURSOR lv_cursor FOR
SELECT carrid, connid, price
FROM sflight
WHERE carrid = 'LH'
ORDER BY price.

DO.
FETCH NEXT CURSOR lv_cursor
INTO TABLE lt_batch
PACKAGE SIZE 100.
IF sy-subrc <> 0.
EXIT.
ENDIF.
" 处理 lt_batch
ENDDO.

CLOSE CURSOR lv_cursor.
步骤 语句 用途
1 OPEN CURSOR c FOR SELECT ... 定义并持有查询
2 FETCH NEXT CURSOR c INTO TABLE ... PACKAGE SIZE n 获取下一批
3 CLOSE CURSOR c 释放资源
💡游标允许你暂停和恢复获取。在需要混合数据库读取与处理,或多个游标需要交错访问时很有用。
⚠️打开的游标占用数据库资源。完成后务必关闭。最大打开游标数受数据库配置限制。

SELECT … ENDSELECT vs INTO TABLE

特性 SELECT … ENDSELECT INTO TABLE
处理方式 逐行(循环) 一次性全部
内存 每次迭代较低 所有行在内存中
性能 更多数据库往返 单次传输
使用场景 需要逐行逻辑时 需要批量数据时
配合 PACKAGE SIZE 受控的分块 不适用

处理顺序汇总

1
2
3
4
5
6
7
8
1. FROM     → 确定源表
2. WHERE → 过滤单个行
3. GROUP BY → 对剩余行分组
4. HAVING → 过滤组
5. SELECT → 应用聚合,选择列
6. DISTINCT → 删除重复项
7. ORDER BY → 排序结果
8. INTO → 传输到 ABAP

考试/测试模式

关键词 / 短语 答案
“HAVING 过滤什么?” 组(GROUP BY 之后),不是单个行
“ORDER BY 位置编号” SELECT 列表中从 1 开始的列位置
“DISTINCT 范围” 整个结果行(不是按列)
“COUNT(*) vs COUNT(col)” COUNT(*) 计算所有行;COUNT(col) 排除 NULL
“何时使用游标?” 精细控制、交错处理、恢复获取
“聚合 + GROUP BY 规则” 所有非聚合的 SELECT 列必须在 GROUP BY 中
“处理顺序” FROM → WHERE → GROUP BY → HAVING → SELECT → DISTINCT → ORDER BY

相关笔记