目录
二、如果要在select的时候只获取字段的某一截数据,可以如何做?
三、在select的时候,可以A=B A=C B=C这样子JOIN吗?
四、如果在join的时候需要表1的字段某几位等于表2的字段的某几位,需要怎么做?
五、如果在select的时候,既要使用SUBSTRING 或者JOIN又要使用FOR ALL ENTRINES IN 怎么解决?
六、如果我将A表和B表连接了,但是只想取B表字段的值,不取A表字段的值,可以如何简单地写?
十、使用FOR ALL ENTRIES IN的时候如果在写WHERE的条件时两个字段的长度不一致,可以如何做呢?
前导:这篇案例总结是平时做开发的时候的一些笔记记录,个人感觉非常有用!涵盖了大部分的开发场景,整篇文章是免费的,文章设置为“关注后可读”,这样我能更直观地了解它是否对大家有帮助,并决定未来是否产出更多类似内容。话不多说,我们直接看正文吧!
一、字段的顺序会导致取数重复吗?
不会,是我inner join的字段判断逻辑写少了,记住inner join、right join、left join的结果都是两个表的数量相乘。
二、如果要在select的时候只获取字段的某一截数据,可以如何做?
使用SUBSTRING,记得加空格,如果是取前6位,就写substring( 字段X,1,6 ) ,表示从第一位取值,取6个字符。

完整代码示例如下:
SELECT D~MATNR,D~VERPR,
SUBSTRING( FKDAT_ANA,1,6 ) AS FKDAT_ANA,
D~LFMON,
SUM( CASE VBTYP_ANA
WHEN 'N' THEN FKIMG * -1
WHEN 'O' THEN FKIMG * -1
ELSE FKIMG END ) AS FKIMG
FROM VBRP
INNER JOIN MARA ON MARA~MATNR = VBRP~MATNR
INNER JOIN MBEWH AS D ON D~MATNR = VBRP~MATNR
AND D~LFGJA = SUBSTRING( FKDAT_ANA,1,4 )
AND D~LFMON = SUBSTRING( FKDAT_ANA,5,2 )
WHERE MARA~MATKL = '20260'
AND VBRP~WERKS IN @P_WERKS
AND D~LFGJA = @GV_LYEAR
AND D~LFMON BETWEEN 01 AND @P_MONAT
AND D~BWKEY IN @P_WERKS
AND VBRP~FKDAT_ANA BETWEEN @LV_DATELS AND @LV_DATELD
AND KTGRM = 'Z1'
GROUP BY D~MATNR,D~VERPR,D~LFMON,FKDAT_ANA
INTO TABLE @DATA(LT_VBRP2).
三、在select的时候,可以A=B A=C B=C这样子JOIN吗?
可以,代码如下:
INNER JOIN T030 ON T030~BKLAS = MBEW~BKLAS
AND T030~BWMOD = T001K~BWMOD
完整代码示例如下:
SELECT
T030~KONTS,
SKAT~TXT20,
MBEW~MATNR,
MBEW~BWKEY
FROM MBEW
INNER JOIN T001K ON T001K~BWKEY = MBEW~BWKEY "评估分组代码
INNER JOIN T030 ON T030~BKLAS = MBEW~BKLAS AND T030~BWMOD = T001K~BWMOD
LEFT JOIN SKAT ON skat~SAKNR = T030~KONTS AND skat~KTOPL = T030~KTOPL
FOR ALL ENTRIES IN @GT_TAB
WHERE T030~KTOSL = 'BSX'
AND T030~KTOPL = '1000'
AND MBEW~MATNR = @GT_TAB-MATNR
AND MBEW~BWKEY = @GT_TAB-WERKS
INTO TABLE @DATA(LT_T030).
四、如果在join的时候需要表1的字段某几位等于表2的字段的某几位,需要怎么做?
也是使用substring,
代码:SUBSTRING( C~KUNAG,5,6 ) = SUBSTRING( A~KUNNR,5,6 )
表明:C表的KUNAG字段的第5位开始,取6个字符,与C表的KUNNR字段的第5位开始,取6个字符,所对应的值相同。
一般可以用于需要连接的两个表中,一个表有前导零,另一个表没有前导零的时候使用,就可以不用去LOOP里面给其中一个表添加前导零了,但是没有试过效率哪个更高。
比如GT_ALV表里面没有前导零,后台表KNVV里面有前导零,这时不想去补充前导零,想直接在SELECT的时候截取或者补充前导零,如何做呢?
完整代码示例如下:
SELECT DISTINCT C~KUNAG,A~BZIRK ,B~BZTXT
FROM KNVV AS A
RIGHT JOIN @GT_ALV AS C ON ( SUBSTRING( C~KUNAG,5,6 ) = SUBSTRING( A~KUNNR,5,6 )
OR C~KUNAG = SUBSTRING( A~KUNNR,5,6 ) )
LEFT JOIN T171T AS B ON A~BZIRK = B~BZIRK
WHERE A~VKORG = @P_BUKRS
* AND B~SPRAS = @SY-LANGU
INTO TABLE @DATA(LT_T171T_INNER).

这里因为GT_ALV里面既有一些有前导零又有一些没前导零,所以使用了一个OR。
五、如果在select的时候,既要使用SUBSTRING 或者JOIN又要使用FOR ALL ENTRINES IN 怎么解决?
既SUBSTRING 又FOR ALL ENTRINES IN时报错如下:
The addition SUBSTRING is not allowed in combination with FOR ALL
ENTRIES. Use JOINs or global temporary tables instead of FOR ALL ENTRIES.
可以使用INNER JOIN 内表 AS XX ON A= A.
如下:

这时候是会黄灯警告的,但是没关系,功能是正常的。
完整代码示例如下:
* 获取批次库存
SELECT B~WERKS,B~LGORT,B~MATNR,CHARG,B~CLABS,'1' AS SOBKZ FROM MCHB AS B
INNER JOIN @LT_TAB1 AS A ON B~WERKS = A~PLANT AND B~MATNR = A~MATNR AND B~LGORT = A~LGORT AND B~CLABS > '0'
INTO TABLE @DATA(LT_MCHB).
* 获取寄售库存
SELECT B~WERKS,B~LGORT,B~MATNR,CHARG,SUM( B~SLABS ) AS CLABS,'2' AS SOBKZ FROM MKOL AS B
INNER JOIN @LT_TAB1 AS A ON B~WERKS = A~PLANT AND B~MATNR = A~MATNR AND B~LGORT = A~LGORT AND B~SLABS > '0'
GROUP BY B~WERKS,B~LGORT,B~MATNR,B~CHARG
INTO TABLE @DATA(LT_MKOL).
六、如果我将A表和B表连接了,但是只想取B表字段的值,不取A表字段的值,可以如何简单地写?
使用B~*
完整代码示例如下:
SELECT B~* FROM ZZT_BZJE AS B
INNER JOIN @LT_LIST AS A ON
B~WERKS = A~WERKS
AND B~LIFNR = A~LIFNR
AND B~MATNR = A~MATNR
AND SUBSTRING( ZQIJIAN ,1,4 ) = A~GJAHR
AND ZQIJIAN = SUBSTRING( A~BUDAT,1,6 )
AND ZDELETE <> 'X'
INTO TABLE @DATA(LT_BZJE).
而这个代码优化前的语句如下:
SELECT * FROM zzt_bzje
FOR ALL ENTRIES IN @lt_list
WHERE werks = @lt_list-werks
AND lifnr = @lt_list-lifnr
AND matnr = @lt_list-matnr
AND zqijian = @lt_list-budat+0(6) " 转换并截取
AND zdelete <> 'X'
INTO TABLE @DATA(lt_bzje).
这个优化前的代码好像会报错,应该是的。可能把@lt_list-budat+0(6)换成@lt_list-budat(6)应该就可行了。
七、这里用了一个left outer join
完整代码示例如下:
SELECT P~MATNR,P~DWERK,P~KDAUF,P~KDPOS,K~AUFNR,K~RSNUM,RESB~MATNR AS MATN1
FROM AFPO AS P
INNER JOIN AFKO AS K ON P~AUFNR = K~AUFNR
LEFT OUTER JOIN RESB ON K~RSNUM = RESB~RSNUM
WHERE P~KDAUF = @T_ITEMIN-VBELN
AND P~KDPOS = @T_ITEMIN-POSNR
AND P~MATNR = @T_ITEMIN-MATNR
AND P~DWERK = @T_ITEMIN-WERKS
AND SUBSTRING( RESB~MATNR,1,5 ) = '31002'
INTO TABLE @DATA(LT_AD)."按单生产的物料数据
忘记了为什么使用outer join,总之是成功了的
八、在SELECT的时候可以直接进行前导零补充吗?
可以,但是没有试过和LOOP添加前导零哪个效率更高,只不过这里是自建的一个配置表,数据很少,所以忽略不计
完整代码示例如下:
SELECT
ZTYPE,
ZTEXT,
LPAD( LTRIM( RACCT ,' ' ), 10, '0' ) AS RACCT
FROM ZFIT0008
WHERE ZTYPE = 'X001'
INTO TABLE @DATA(LT_ZT08).
九、记住SELECT SINGLE需要加前导零
SELECT SINGLE 需要加前导零,不然会找不到数据

十、使用FOR ALL ENTRIES IN的时候如果在写WHERE的条件时两个字段的长度不一致,可以如何做呢?
有两个方法可以解决,一是可以在定义字段的时候将字段定义成一致,;二是使用CAST转换字段的数据类型,不过使用了CAST就需要将FOR ALL ENTRIES IN修改为 JOIN.

这里就是VBFA的RFMNG字段的类型是CURR 长度13带有3个小数,ACDOCA的MSL字段类型是CURR长度23带有3个小数。
方法一:

将内表里面的字段类型定义成和VBFA里面的一致,就不会报错了。
方法二、使用CAST,转换其中任意一个都可以

CAST完整代码示例如下::
SELECT A~* FROM VBFA AS A
INNER JOIN @LT_A AS B ON A~VBELV = B~KDAUF
AND CAST( RFMNG AS CURR( 23,3) ) = B~MSL
INTO TABLE @DATA(LT_VBFA1).
希望对大家有所帮助,后面我会补充更多的~
浙公网安备 33010602011771号