Appearance
OPEN SQL 读取数据
一、 数据查询 (SELECT)
1.查询sql语法:
abap
SELECT [SINGLE] <字段列表>
FROM <表名>
[INTO|APPENDING <目标结构>]
[WHERE <条件>]
[GROUP BY <分组字段>]
[HAVING <分组条件>]
[ORDER BY <排序字段>].
ENDSELECT. " 仅用于逐行读取模式
- 单行查询:
SELECT SINGLE
用于精确匹配单条记录,需配合唯一条件使用; 示例:SELECT SINGLE name INTO @DATA(lv_name) FROM zuser WHERE id = '001'
- 动态查询:支持运行时指定字段列表8 示例:
SELECT (lv_fields) FROM ztable INTO TABLE @DATA(lt_data)
- 结果处理:
INTO TABLE
直接填充内表APPENDING
追加数据到现有内表3
2.去重查询 DISTINCT
abap
SELECT DISTINCT carrid FROM sflight INTO TABLE @DATA(lt_airlines)
- 自动过滤重复记录,常用于枚举值查询
- 注意:大数据量使用可能导致性能问题
二、数据检索变式
1.单行查询
abap
SELECT SINGLE <字段>
FROM <表名>
INTO @DATA(ls_data)
WHERE <唯一条件>.
- 必须指定唯一条件字段(主键优先)
2. 动态字段选择
abap
DATA(lv_fields) = 'CARRID, CONNID'.
SELECT (lv_fields)
FROM sflight
INTO TABLE @DATA(lt_dyn).
- 支持运行时动态指定字段列表
3.联合查询
abap
SELECT a~carrid, b~connid
FROM spfli AS a
INNER JOIN sflight AS b
ON a~carrid = b~carrid
INTO TABLE @DATA(lt_join).
- 支持
INNER JOIN/LEFT OUTER JOIN
INNER JOIN
- 定义:仅返回两个表中完全匹配的记录,未匹配数据自动过滤
- ABAP 语法:abap
SELECT a~carrid, b~connid FROM spfli AS a INNER JOIN sflight AS b ON a~carrid = b~carrid INTO TABLE @DATA(lt_data)
LEFT OUTER JOIN
- 定义:返回左表全部记录 + 右表匹配记录(无匹配时右表字段为 NULL)47
- 典型场景:需包含主表全部数据(如订单主表+详情表关联)4
RIGHT OUTER JOIN
- 定义:返回右表全部记录 + 左表匹配记录(使用频率较低)
4.内标筛查(FOR ALL ENTRIES)
FOR ALLENTRY语句与嵌套SELECT语句或Subquery的功能相似。使用FOR ALL ENTRY语句时,WHERE语句中使用的条件必须是itab中存在的字段。
abap
DATA(lt_filter) = VALUE RANGE(...).
SELECT * FROM sflight
INTO TABLE @DATA(lt_filtered)
FOR ALL ENTRIES IN @lt_filter
WHERE carrid = @lt_filter-carrid
注意:
- itab的字段要与比较对象的表字段类型一致。
- 不能使用类似LIKE、BETWEEN、IN等比较语句itab 中自动删除重复数据(Unique Key为基准)。
- itab为空则取得所有数据。
- itab 中数据多时会增加LOOP 循环次数,因此会降低选择速度。例如 itab 中数据为 3 条,则会执行3次“SELECT~ENDSELECT”。
[案例]是先查询存储航班时刻表的数据库表spfi 的所有数据后用FOR ALLENTRIES语句从日期别航班运行信息数据库表中查询相关数据的程序。
abap
REPORT z03 10.
DATA gt spfli TYPE TABLE OF spfli.
DATA gt sflight TYPE TABLE OF sflight.
DATA gs sflight TYPE sflight.
SELECT * FROM spfli
INTO TABLE gt spfli.
SELECT * FROM sflight
INTO TABLE gt sflight
FOR ALL ENTRIES IN gt spfli
WHERE carrid =gt spfli-carrid
AND connid = gt spfli-connid.
LOOP AT gt sflight INTo gs sflight.
WRITE : /gs sflight-carrid, gs sflight-connid.
ENDLOOP.
三、WHERE 子句条件类型
条件类型 | 语法示例 | 适用场景 |
---|---|---|
精确匹配 | WHERE carrid = 'LH' | 主键/索引字段查询 |
范围查询 | WHERE fldate BETWEEN '20250101' AND '20251231' | 日期/数值区间筛选 |
模糊查询 | WHERE cityfrom LIKE 'Frank%' | 部分字符串匹配场景 |
集合筛选 | WHERE carrid IN ('LH','AA','DL') | 多值筛选场景 |
动态条件 | WHERE (lv_where_cond) (lv_where_cond = carrid = 'LH') | 运行时条件动态生成 |
关键特性说明
- 精确匹配:通过等号直接定位特定值,适用于主键或二级索引字段的高效检索;
- 范围查询:使用
BETWEEN
运算符快速筛选连续区间数据(如时间范围、金额区间); - 模糊查询:利用
LIKE
配合通配符%
或_
进行模式匹配,常用于模糊搜索场景; - 集合筛选:通过
IN
运算符批量匹配多个离散值,优化多值查询性能; - 动态条件:支持运行时拼接条件字符串,实现灵活的条件组合逻辑。
四、高级功能
1. 分组统计
abap
SELECT carrid, SUM( price ) AS total
FROM sflight
GROUP BY carrid
HAVING total > 10000
INTO TABLE @DATA(lt_sum).
GROUP BY
与聚合函数配合使用HAVING
过滤分组结果
聚合函数与分组统计一起使用
函数 | 描述 | 示例 | 备注 |
---|---|---|---|
COUNT(*) | 统计查询结果记录总数 | COUNT(*) AS cnt | 包含NULL值记录统计 |
SUM() | 数值型字段求和 | SUM( price ) AS total | 仅对数值字段有效 |
AVG() | 计算数值字段平均值 | AVG( price ) AS avg_price | 自动排除NULL值计算 |
MAX() | 获取字段最大值 | MAX( fldate ) AS last_date | 支持日期/数值/字符型 |
使用示例
abap
" 航班数据统计查询
SELECT carrid,
COUNT(*) AS flight_count,
SUM( seatsocc ) AS occupied_total,
AVG( price ) AS average_price,
MAX( fldate ) AS last_flight_date
FROM sflight
INTO TABLE @DATA(lt_stats)
GROUP BY carrid. -- 必须使用GROUP BY分组
使用注意:
- 1.NULL值处理:AVG()函数自动忽略NULL值,COUNT(*)包含所有记录
- 2.数据类型匹配:SUM()/AVG()仅适用数值字段,MAX()支持排序字段
- 3.分组要求:使用聚合函数时必须搭配GROUP BY子句(COUNT(*)除外)
2. 子查询应用
abap
SELECT * FROM sflight
WHERE carrid IN (
SELECT carrid FROM spfli
WHERE countryto = 'CN'
).
- 支持
IN、EXISTS
等子查询类型
3.结果排序 (ORDER BY)
abap
SELECT * FROM sflight
INTO TABLE @DATA(lt_sorted)
ORDER BY fldate DESCENDING, carrid ASCENDING
4. 游标分页
abap
DATA: lv_cursor TYPE cursor.
OPEN CURSOR lv_cursor FOR
SELECT * FROM sflight WHERE carrid = 'LH'.
FETCH NEXT CURSOR lv_cursor
INTO TABLE @DATA(lt_page) PACKAGE SIZE 100.
- 适用于大数据量分批次处理
五、性能优化要点
- 行数限制:
UP TO 100 ROWS
限制返回行数 - 字段精简:避免
SELECT *
,明确指定必要字段 - 索引匹配:WHERE条件优先使用索引字段
- 批量操作:减少循环中执行
SELECT
次数
六、综合应用示例
abap
" 分页查询+动态字段+分组统计
DATA: lv_fields TYPE string VALUE 'CARRID, AVG( PRICE ) AS avg_price',
lv_offset TYPE i VALUE 0.
DO 3 TIMES.
SELECT (lv_fields)
FROM sflight
GROUP BY carrid
ORDER BY avg_price DESC
INTO TABLE @DATA(lt_report)
UP TO 50 ROWS
OFFSET @lv_offset.
lv_offset = lv_offset + 50.
ENDDO.