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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了工作笔记之 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​​ 表中选取 ​​carrid​​ 为 ​​LH​​ 的信息:

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 = LH​​ 和 ​​Flight 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 结尾的航线代码的相关信息,此处包括 ​​DL​​ 和 ​​JL​​:

工作笔记之

当使用 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_value
DATA 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 中有很多方便查询的操作,比如:​​WHERE​​、​​GROUP​​、​​ORDER​​、​​FOR ALL ENTRIES​​ 等等,希望对你帮助。

以上是关于工作笔记之 SELECT 语句在 SAP ABAP 中的用法总结(下)的主要内容,如果未能解决你的问题,请参考以下文章

工作笔记之 SELECT IN ABAP

SAP ABAP select 语句为啥取不到数据(确认后台表中有数据)

SAP-ABAP SELECT-SCREEN

第二篇SAP ABAP7.50新语法之OPEN SQL

ABAP系列SAP ABAP SY-SUBRC的含义解析

第一篇SAP ABAP7.50新语法之预定义数据结构