SELECT * FROM dd_view_name INTO TABLE lt_data WHERE ...
💡数据库视图封装 JOIN 逻辑。使用它们简化 ABAP 代码中重复的 JOIN。
INNER JOIN(内连接)
仅返回两表中匹配的行
最常见的 JOIN 类型
1 2 3 4 5 6 7
SELECT s~carrid, s~connid, p~cityfrom, p~cityto INTO TABLE lt_result FROM sflight AS s INNER JOIN spfli AS p ON s~carrid = p~carrid AND s~connid = p~connid WHERE s~carrid = 'LH'.
1 2 3 4 5 6 7 8 9 10 11 12 13 14
表 A(左) 表 B(右) +----+------+ +----+-------+ | K1 | A1 | | K1 | B1 | +----+------+ +----+-------+ | 01 | X | | 01 | Y | | 02 | Z | | 03 | W | +----+------+ +----+-------+
SELECT s~carrid, s~connid, p~cityfrom INTO TABLE lt_result FROM sflight AS s LEFT OUTER JOIN spfli AS p ON s~carrid = p~carrid AND s~connid = p~connid.
1 2 3 4 5 6 7
LEFT OUTER JOIN 结果: +----+------+----+-------+ | K1 | A1 | K1 | B1 | +----+------+----+-------+ | 01 | X | 01 | Y | ← 找到匹配 | 02 | Z | -- | NULL | ← 无匹配,右侧为 NULL +----+------+----+-------+
FROM sflight AS s INNER JOIN spfli AS p ON s~carrid = p~carrid " alias~column 表示法
表示法
含义
alias~column
限定来自特定表的列
~column
快捷方式(如果不歧义)
裸 column
如果在多个表中则歧义
子查询
标量子查询
在 WHERE 子句中返回单个值:
1 2 3
SELECT * FROM sflight INTO TABLE lt_flights WHERE price > ( SELECT AVG(price) FROM sflight ).
IN 子查询
返回一组值:
1 2 3
SELECT * FROM sflight INTO TABLE lt_result WHERE carrid IN ( SELECT carrid FROM scarr WHERE currcode = 'EUR' ).
子查询类型
返回值
配合使用
标量
单个值
=、<、> 等
集合
多个值
IN、NOT IN
📌子查询绕过 SAP 表缓冲(被缓冲视为 Native SQL 路径)。
FOR ALL ENTRIES
将数据库表与内表连接:
1 2 3 4 5 6 7 8 9
" 关键:先检查驱动表! IF lt_keys IS NOT INITIAL. SELECT carrid, connid, price INTO TABLE lt_result FROM sflight FOR ALL ENTRIES IN lt_keys WHERE carrid = lt_keys-carrid AND connid = lt_keys-connid. ENDIF.
FOR ALL ENTRIES 规则
规则
详情
检查 IS NOT INITIAL
空驱动表读取整个数据库表
自动去重
结果自动删除重复行
不适用于大数据量
驱动表很大时性能下降
不能使用 LIKE、NOT IN
WHERE 中受限的运算符
⛔如果驱动表(内表)为空,FOR ALL ENTRIES 的行为如同没有 WHERE 子句,读取整个数据库表。始终先检查 itab IS NOT INITIAL!
性能提示
1 2 3 4 5 6 7 8 9 10 11 12
" 不好:驱动表未排序、有重复 SELECT * FROM sflight FOR ALL ENTRIES IN lt_dirty WHERE carrid = lt_dirty-carrid.
" 好:先精简驱动表 SORT lt_dirty BY carrid. DELETE ADJACENT DUPLICATES FROM lt_dirty COMPARING carrid.
SELECT * FROM sflight FOR ALL ENTRIES IN lt_dirty WHERE carrid = lt_dirty-carrid.
性能反模式:循环中的 SELECT
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
" 反模式:循环中的 SELECT LOOP AT lt_flights INTO ls_flight. SELECT SINGLE cityfrom INTO ls_flight-cityfrom FROM spfli WHERE carrid = ls_flight-carrid AND connid = ls_flight-connid. MODIFY lt_flights FROM ls_flight. ENDLOOP.
" 正确:使用 JOIN 或预缓冲 SELECT s~carrid, s~connid, p~cityfrom INTO TABLE lt_result FROM sflight AS s INNER JOIN spfli AS p ON s~carrid = p~carrid AND s~connid = p~connid.
方式
数据库往返次数
性能
循环中的 SELECT
n + 1(每行一次)
很差
JOIN
1
优秀
FOR ALL ENTRIES
1(或少量)
小集合时良好
预缓冲 + READ
1 + 内存查找
良好
JOIN 比较
特性
INNER JOIN
LEFT OUTER JOIN
未匹配的左表行
丢弃
保留(右侧 = NULL)
右侧限制
无
仅一个表
绕过缓冲
是
是
ON 条件
必需
必需
默认 JOIN 类型
INNER(关键字可选)
必须指定 OUTER
考试/测试模式
关键词 / 短语
答案
“FOR ALL ENTRIES 空表”
读取整个数据库表 – 始终检查 IS NOT INITIAL
“LEFT OUTER JOIN 右侧限制”
右侧只允许一个表
“JOIN 和表缓冲”
JOIN 绕过 SAP 表缓冲
“别名列语法”
alias~column 消除歧义
“FOR ALL ENTRIES 去重处理”
结果集自动删除重复项
“循环中的 SELECT”
反模式;使用 JOIN 或预缓冲
“精简驱动表”
FOR ALL ENTRIES 前 SORT + DELETE ADJACENT DUPLICATES