写点什么

工作笔记之 SELECT 语句在 SAP ABAP 中的用法总结(下)

作者:宇宙之一粟
  • 2022 年 9 月 25 日
    广东
  • 本文字数:3936 字

    阅读完需:约 13 分钟

工作笔记之 SELECT 语句在 SAP ABAP 中的用法总结(下)

引言

上一篇文章中,我们介绍了 ABAP 的查询语句关键的三个部分:

  1. SELECT result 部分

  2. FROM source 部分

  3. INTO target 部分


常见语法:

SELECT result  FROM source  INTO target  [WHERE condition]  [GROUP BY fields]  [HAVING cond]  [ORDER BY fileds].
复制代码

并介绍了上述三个主体部分的使用方法,这篇文章我将来介绍后续能在 SELECT 操作的可选部分,并借此来帮助我们进行高效的查询。主要包括如下:

  • WHERE 条件

  • IN 操作符

  • GROUP BY

  • HAVING

  • ORDER BY

  • UP TO N ROWS

  • FOR ALL ENTRIES

  • 子查询


同时,从 SAP NetWeaver 7.5 开始,UNION 方法可以用来在两个 SELECT 语句的结果集之间创建一个联合。

WHERE 条件

WHERE 条件后面跟随的是查询的限制条件。也是 SELECT 查询中最常被使用的条件,因为我们在实际情况中并非总是需要获取所有数据,所以需要有条件的进行查询。


WHERE 基本用法:选取某个字段的某个情况。比如我们从 sflight 表中选取 carridLH 的信息:


SELECT carrid connid    FROM sflight   INTO CORRESPONDING FIELDS OF TABLE gt_out   WHERE carrid = 'LH'.
复制代码



可以看到,这次查询只返回 carrid = LH 的结果集。


如果想使用多个条件,可以使用 AND 连接多个字段,如:

SELECT mandt carrid connid fldate  FROM sflight  INTO CORRESPONDING FIELDS OF TABLE gt_out  WHERE carrid = 'LH'    AND connid = '402'.
复制代码


条件运算符

WHERE 可以使用的条件运算符很多:


  • EQ (或 = 号,即等于)

  • NE (或 <> 号,即不等于)

  • LT (或 < 号,即小于号)

  • GT (或 > 号。即大于号)

  • LE(或 <= 号,即小于等于)

  • GE (或 >= 号,即大于等于)

  • BETWEEN (范围运算符)


比如使用与字段不相等的示例:

SELECT mandt carrid connid fldate  FROM sflight  INTO CORRESPONDING FIELDS OF TABLE gt_out  WHERE carrid NE 'LH'    AND connid <> '402'.
复制代码

运行结果如下,不会存在 Airline = LHFlight No. = 402 的结果:

范围运算符那 BETWEEN 举例:

SELECT mandt carrid connid fldate  FROM sflight  INTO CORRESPONDING FIELDS OF TABLE gt_out  WHERE carrid BETWEEN 'DL' AND 'LH'.
复制代码


字符串匹配

LIKE 运算符可以有助于更好的从表里获取数据,只使用搜索部分字符,用法如下:LIKE 'XXX_'.


其中 XXX 代表我们正在寻找的单词的一部分,而 _ 下划线就代表任何其他的符号集,可以表示任何字母。比如想寻找以 L 结尾的 carrid 信息,就可以使用如下的代码:

SELECT mandt carrid connid fldate  FROM sflight  INTO CORRESPONDING FIELDS OF TABLE gt_out  WHERE carrid LIKE '_L'.
复制代码

最后查询的结果就会包括以 L 结尾的航线代码的相关信息,此处包括 DLJL

当使用 LIKE 时,我们必须有字符作为一个值。然而,如果我们想使用非字符格式,我们可以尝试使用 CAST


sflight 表中,我们有 CONNID,例如,它不是字符类型。

但是我们也想同样使用类似字符匹配的功能,就可以使用 CAST:

SELECT mandt, carrid, connid, fldate  FROM sflight  WHERE CAST( connid AS CHAR ) LIKE '19__'  INTO CORRESPONDING FIELDS OF TABLE @gt_out.
复制代码

比如上面的代码中,就想要找到以数字 19 开头的 connid 信息,查询结果如下:


这里有几个变化需要注意,首先:

  1. 需要用逗号将字段隔开,不然有如下报错:

  1. INTO 或者 APPENDING 需要放到查询语句的最后,不然又如下报错:

  1. 需要给内表加上 @ 符号,这个方式是 ABAP 7.4 SP05 以上版本提供的内联定义:

IN 条件运算符

IN 运算符用于在 SELECT 查询中创建一个范围,比如我们可以用括号包裹起来,在这个范围的结果都可以被查询出来,比如找出 carrid 为 AA、DL、LH 的信息:

SELECT carrid connid FROM sflight  INTO CORRESPONDING FIELDS OF TABLE gt_out    WHERE carrid IN ('AA', 'DL', 'LH').
复制代码

除了在表中的字段,IN 还可以来使用选择屏幕中的范围,部分用法如下:

INTO CORRESPONDING FIELDS OF TABLE gt_out   WHERE a~vbeln IN so_vbeln    AND a~posnr IN so_posnr    AND b~erdat IN so_erdat.
复制代码

更高级 IN 用法是使用范围表,四个字段:

  • SIGN

  • OPTION

  • LOW

  • HIGH

WHERE 中的动态 SELECT 查询

如果我们不知道我们在 WHERE 条件中需要什么字段,我们可以使用动态的 WHERE 条件,通过在运行时决定哪个字段被添加到 WHERE 条件中。

" 设定条件语句的格式为:gv_field = gv_valueDATA gv_where TYPE c LENGTH 100.DATA gv_field TYPE c LENGTH 50 VALUE 'carrid'.DATA gv_operator TYPE C LENGTH 10 VALUE 'EQ'.DATA gv_value TYPE c LENGTH 50 VALUE '''LH'''.
CONCATENATE gv_field gv_operator gv_value INTO gv_where SEPARATED BY space.
" 查询数据,动态传入条件语句SELECT mandt carrid connid FROM sflight INTO CORRESPONDING FIELDS OF TABLE gt_out WHERE (gv_where).
复制代码

统一能获取结果:

SINGLE FOR UPDATE

FOR UPDATE 语句可以用来为选定的行设置一个独占锁。然而,如果我们有一个以上的条目具有相同的主键,结果集将是空的。因此,指定全部的主键真的很重要。


此外,当我们的 FOR UPDATE 语句导致死锁时,将引发一个异常,SELECT 语句绕过 SAP 缓冲也很重要。


  SELECT SINGLE FOR UPDATE carrid connid     FROM sflight    INTO CORRESPONDING FIELDS OF TABLE gs_out    WHERE carrid EQ 'AA'.
复制代码


GROUP BY

GROUP BY 用于分组查询,如分组求和的查询。


SELECT carrid connid  FROM sflight  INTO CORRESPONDING FIELDS OF TABLE gt_sflight  GROUP BY carrid connid.
复制代码


GOURP BY 可以配合使用 AVG 平均值、COUNT 计数、MAX/MIN 取最大值/最小值、SUM 取和计算、STDDEV 取标准差等聚合方法进行查询分组计算。


HAVING 后的条件语句用于限制,在使用 GROUP BY 确定分组条件的语句。


ORDER BY

用于按 fields 指定的字段进行由小到大的排序,也可以使用主键 PRIMARY KEY 进行排序,这种情况再表连接和视图查询时不能使用:

SELECT carrid connid  FROM sflight  INTO CORRESPONDING FIELDS OF TABLE gt_sflight  ORDER BY PRIMARY KEY.
复制代码


它还可以以升序或降序对其他列进行排序,通过加上 ASCENDING 或者 DESCENDING :

SELECT carrid connid planetype  FROM sflight  INTO CORRESPONDING FIELDS OF TABLE gt_sflight  ORDER BY planetype ASCENDING.
复制代码


UP TO ROWS

UP TO (natural number) ROWS 用来增加一个限制:来限定可以被查询到的行数。如下,限定 10 行:


SELECT carrid connid planetype  UP TO 10 ROWS  FROM sflight  INTO CORRESPONDING FIELDS OF TABLE gt_sflight.
复制代码


FOR ALL ENTRIES

FOR ALL ENTRIES 可以在两个表的情况下,我们想根据第一个表的字段,从第二个表中获取数据。


SELECT carrid connid  FROM sflight  INTO CORRESPONDING FIELDS OF gt_sflight  WHERE planetype = '747-400'.
IF gt_sflight IS NOT INITIAL. SELECT carrid connid counryfr cityfr airpfrom countryto FROM spfli INTO CORRESPONDING FIELDS OF TABLE gt_spfli FOR ALL ENTRIES IN gt_sflight WHERE carrid = gt_sflight-carrid AND carrid = gt_sflight-connid.ENDIF.
复制代码

在第一条 SELECT 语句中,我们得到了关于 carrid 和 connid 的数据,但是只有当 planetype 是 '747-400'。在第二个表中,由于我们没有 planetype ,我们只能得到我们想要的行。


在使用 FOR ALL ENTRIES 时,我们需要记住的一件事是,我们需要在执行带有 FOR ALL ENTRIES 的 SELECT 之前,要检查使用该表的表是否为空。


如果表是空的,在这个例子中,所有的记录都将从 spfli 表中获得。

子查询


子查询可以在 WHERE 条件中使用,直接从另一个表中获得最大值。例如,在使用 SUBQUERY 时,可以增加以下内容:

  • ALL | ANY | SOME

  • EXIST

  • IN


如果,我们想预定一个价格最高的航班,可以使用如下代码:

SELECT *  FROM sflight  INTO CORRESPONDING FIELDS OF gt_sflight  WHERE price = ( SELECT MAX( price ) FROM sflight ).
复制代码


JOIN

如果我们在许多表中进行查询,就不得不用上 JOIN 语句,ABAP 中有两种类型的连接在数据库表中进行数据查询:

  • INNER JOIN: 内连接需要在第二个表中提取带有一个表的主键的条目到一个内部表中。

  • OUTER JOIN:外连接不管第二张表中是否有条目存在,仍然是从第一个表中提取数据。


INNER JOIN 代码示例:

SELECT        KNA1~KUNNR        KNA1~NAME1        KNA1~NAME2        KNA1~SORTL        KNA1~LAND1        KNA1~REGIO        KNA1~ADRNR        KNA1~KTOKD        KNA1~ERDAT        KNA1~ERNAM        KNVV~VKORG        KNVV~VTWEG        KNVV~BZIRK        KNVV~VKBUR        KNVV~VKGRP        KNVV~WAERS        KNVV~KTGRD        KNVV~ZTERM        KNVV~KDGRP        KNVV~INCO1        KNVV~INCO2      FROM  KNA1       INNER JOIN KNVV ON KNA1~KUNNR EQ KNVV~KUNNR      INTO CORRESPONDING FIELDS OF TABLE GT_OUT.
复制代码


OUT JOIN 代码示例:

SELECT      KNA1~KUNNR      KNA1~NAME1      KNA1~NAME2      KNA1~SORTL      KNA1~LAND1      KNA1~REGIO      KNA1~ADRNR      KNA1~KTOKD      KNA1~ERDAT      KNA1~ERNAM      KNB1~BUKRS      KNA1~AUFSD      KNA1~LIFSD      KNA1~FAKSD      KNB1~AKONT      KNB1~ZTERM      SKAT~TXT50    FROM  KNA1    INNER JOIN KNB1 ON KNA1~KUNNR = KNB1~KUNNR    LEFT OUTER JOIN SKAT ON KNB1~AKONT = SKAT~SAKNR AND SKAT~KTOPL = 'HM00' AND SKAT~SPRAS = SY-LANGU    INTO CORRESPONDING FIELDS OF TABLE GT_OUT.
复制代码


总结

至此,本文总结了跟在 SELECT 语句后的条件。ABAP 中有很多方便查询的操作,比如:WHEREGROUPORDERFOR ALL ENTRIES 等等,希望对你帮助。


发布于: 刚刚阅读数: 3
用户头像

宇宙古今无有穷期,一生不过须臾,当思奋争 2020.05.07 加入

🏆InfoQ写作平台-第二季签约作者 🏆 混迹于江湖,江湖却没有我的影子 热爱技术,专注于后端全栈,轻易不换岗 拒绝内卷,工作于软件工程师,弹性不加班 热衷分享,执着于阅读写作,佛系不水文

评论

发布
暂无评论
工作笔记之 SELECT 语句在 SAP ABAP 中的用法总结(下)_数据库_宇宙之一粟_InfoQ写作社区