SAP ABAP openSQL数据库操作(一)
SAP ABAP openSQL数据库操作(三)
SAP ABAP openSQL数据库操作(四)
多表联查的方式有左连接,内连接,右连接,子查询等,理论上来说子查询的效率是最低的.
*一个select的结果做另一个的select的条件
SELECT carrid connid
FROM spfli
INTO (wa_carrid,wa_connid)
WHERE cityfrom = 'SINGAPORE'.
SELECT carrname
FROM scarr
INTO wa_carrname
WHERE carrname = 'wa_carrid'.
WRITE / wa_carrname.
ENDSELECT.
ENDSELECT.
以上面的SQL为例,他是把WHERE cityfrom = 'SINGAPORE'
这个所有满足条件的FOR ALL ENTRIES
到一个内表中,然后在根据这个内表中的数据再去查询相应的结果.
一旦指定了FOR ALL ENTRIES
到的那个内表的某一个字段,相当于指定了该内表的所有字段值.
使用该结构时要确保数据库字段与内表中关联的字段保持一致性.
语法 :
SELECT * FROM ALL ENTRIES IN itab WHERE <condition>.
示例:
这个两个select不是嵌套关系,而是并联关系.
SELECT carrid connid
FROM spfli
INTO (wa_carrid,wa_connid)
WHERE cityfrom = 'SINGAPORE'.
SELECT carrname
FROM scarr
INTO wa_scarr
FOR ALL ENTRIES IN spfli_tab1
WHERE carrname = spfli_tab1-carrid.
WRITE / wa_carrname.
ENDSELECT.
ENDSELECT.
包括 inner join
和left outer join
inner join
取两张表的交集
SELECT * FROM table
INNER JOIN jointtable1 [AS jt1] ON <condition>
INNER JOIN jointtable2 [AS jt2] ON <condition>
table
为主表其他的为结合表AS
的是别名,
每一个条件中必须包含一个主表的字段.
SELECT spfli~carrid ,scarr~carrname ,spfli~connid
FROM spfli
INNER JOIN scarr ON scarr~carrid = spfli~carrid
INTO (wa_carrid,wa_connid,wa_carrname)
WHERE spfli~cityfrom = 'SINGAPORE'.
ENDSELECT.
left outer join
与inner join
主要区别是左连接中,对于主选择表的数据,即使在结合表中条件字段值不存在,也将该数据行选出,结合表中不存在的字段保持空白,
在NO
中只能使用 “=” 操作符,且必须至少有一个条件是对主表和结合表中的字段进行比较
如图:
SELECT * FROM table
LEFT JOIN jointtable1 [AS jt1] ON <condition>
如果在一个表中查询数据时需要与其他表中的某些字段相关联,则可以使用子查询.
子查询没有INTO
语句,是用EXISTS
IN
WHERE
进行连接,不可结合NO
同时使用.
1. 使用EXISTS
SELECT * FROM scarr
INTO TABLE wa_scarr
WHERE EXISTS ( SELECT * FROM spfli WHERE carrid = scarr~carrid AND cityfrom = 'SINGAPORE' ).
2. 使用IN
则需要子查询返回字段
SELECT * FROM scarr
INTO TABLE wa_scarr
WHERE city IN ( SELECT * FROM spfli WHERE carrid = scarr~carrid AND cityfrom = 'SINGAPORE' ).
3. 使用=
逻辑运算需要区分单行和多行的结果集
单行结果集
SELECT * FROM scarr
INTO TABLE wa_scarr
WHERE city = ( SELECT * FROM spfli WHERE carrid = scarr~carrid AND cityfrom = 'SINGAPORE' ).
4. 多行结果集.多行的需要注意的是在子查询之前需要注明 ALL
ANY
SOME
ALL
表示满足条件的所有行;
ANY SOME
表示至少有一行满足的
SELECT * FROM scarr
INTO TABLE wa_scarr
WHERE city > ALL ( SELECT * FROM spfli WHERE carrid = scarr~carrid AND cityfrom = 'SINGAPORE' ).
MAX(最大值) MIN(最小值) SUM(和) AVG(平均值) COUNT(行数)
语法:
SELECT agg ( [DISTINCT] s ) [AS a1]...
s1为字段,a1位目标变量
SELECT carrid connid sum( seatsocc )
FROM sflight
INTO (wa_carrid,wa_connid,sum_seatsocc)
WHERE spli~cityfrom = 'SINGAPORE'.
上述中的sum( seatsocc )
的结果或存放在变量sum_seatsocc
可以使用GROUP BY
进行分组.
试讲数据库表中一组某些指定字段值相同的行中的内容组合到单行中,其他字段则可以通过总计功能进行求和.
分组总计只能应用在查询中,因此只有指定单独基本字段列表或使用INTO CORRESPONDING FIELDS
的SELECT
语句方可.
语法:
SELECT s1 [AS a1] s2 [AS a2]
agg( s3 ) [AS a3]
INTO (f1,f2,f3) | CORRESPONDING FIELDS OF itab
GROUP BY s1 s2 ..
上述的s1 s2字段值全部相同的字段数据行被组合成一行,而s3字段则需要进行统计字段.
SELECT carrid MIN( price ) MAX( price )
INTO (carrid, min_mun,max_mun)
FROM sflight
GROUP BY carrid.
ENDSELECT.
给分组添加条件使用HAVING
他的作用是和WHERE
一样 .
SELECT s1 [AS a1] s2 [AS a2]
agg( s3 ) [AS a3]
INTO (f1,f2,f3) | CORRESPONDING FIELDS OF itab
GROUP BY s1 s2
HAVING <condition>.
但是注意区分,前者一般只用于分组,后者一般使用其他的条件查询.
SELECT carrid MIN( price ) MAX( price )
INTO (carrid, min_mun,max_mun)
FROM sflight
GROUP BY carrid
*只筛选大于1000的数据
HAVING MIN(min_mun) > 1000.
ENDSELECT.
排序分升序ASCENDING
和降序DESCENDING
系统默认是升序,排序是从左到右进行.
如果数据库系统查询和排序使用的是相同的索引时一般会在SQL上进行排序,否则就是SELECT
完之后再通过SORT BY f1 f2 f3..
对内表字段进行排序.
SELECT carrid MIN( price ) MAX( price )
INTO (carrid, min_mun,max_mun)
FROM sflight
GROUP BY carrid
ORDER BY carrid ASCENDING
max DESCENDING.
ENDSELECT.
db_name
这个变量字符必须是大写的.
不能使用表工作区忽略into子句
SELECT * FROM (db_name)..
db_name = 'SPFLI'
SELECT carrid FROM (db_name)
INTO (carrid)
WHERE cityfrom = 'BIEJING'.
每张数据库表都会一个主键字段"集团",在我们进行数据库操作的时候系统就会自动指定集团处理,如果要不想处理该集团可以使用语句CLIENT SPECIFED
来取消自盾构处理的功能
SELECT|UPDATE * datab CLIENT SPECIFED..
该语句必须在数据库表后面.
关闭后我们使用WHERE
语句货工作区指定abap中的集团字段.
SELECT * FROM spfli CLIENT SPECIFIED
INTO TABLE wa_spfli
WHERE mandt BETWEEN '100' AND '102'.
这样语句就会查询集团100到102中存储的数据,而不会考虑用户登录的集团id.
数据库表的缓冲机制是和Redis的作用是类似的,都用来存放临时数据.但该缓冲机制的功能可没有Redis的功能强大.Redis参考1 / Redis参考2
而该缓冲机制是把首次读取到的数据储存到应用服务器内存中.
可分为表内容缓冲;部分内容缓冲;单行数据缓冲.
我们在使用缓冲机制的时候应当注意与数据库的一致性检查,防止脏读幻读等形式的数据错误.
使用语句BYPASSING BUFFER
注意:在使用数据去重函数查空值组排序时将自动忽略缓冲设定.
SELECT * FROM dbtab BYPASSING BUFFER..
指定查询多少行数据
SELECT * FROM dbtab UP TO n ROWS
如果n>0最多选n行
如果n=0选择所有满足条件的
如果使用ORDER BY 系统有限选择满足条件的,然后排序,最后选择前n行数据.
使用GET RUN TIME
获取系统当前运行事件
GET RUN TIME FIELD f.
f为int类型字段 f/ms
REPORT z_runtime_analysis.
DATA:wa_carrid TYPE spfli-carrid,
wa_connid TYPE spfli-connid,
wa_carrname TYPE scarr-carrname.
DATA:t1 TYPE i,
t2 TYPE i,
time TYPE i,
n TYPE i VALUE 1000.
DO n TIMES.
GET TIME FIELD t1.
SELECT carrid connid
FROM spfli
INTO (wa_carrid,wa_connid)
WHERE cityfrom = 'SINGAPORE'.
SELECT carrname
FROM scarr
INTO wa_carrname
WHERE carrid = wa_carrid.
ENDSELECT.
ENDSELECT.
GET TIME FIELD t2.
time = time + t2 - t1.
ENDDO.
WRITE : / 'runtime:', time.
需要对复杂的程序进行分析可以使用SE30
参考:SAP ABAP debug的七种方法及错误消息定位第五个使用的就是SE30
这个工具
8.使用光标