COUNT returns 个含 NULL 的 LEFT JOIN 查询结果不明确
COUNT returns ambiguous result for LEFT JOIN query with NULLs
是否可以count
left join
的记录?我想查看 count
return 实际加入的记录(包括 0
如果什么都没有加入)。
像下面这样的连接在我使用的其他形式的 SQL 中工作,但 OpenSQL 似乎不支持 count([column])
:
select header~key, count(item~key)
from header left join item on header~key = item~header_key
group by header~key.
我知道以下查询有效,但是 如果没有 items
与 header 连接,计数仍为 1 而不是 0:
select header~key, count(*) from header left join item group by header~key.
目前,我已在需要时使用 abap(loop
和 loop at
加上 group
)进行计数。
在我当前的场景中,我正在处理交易数据,与我以前的项目相比,这是巨大的,额外的循环会大大增加处理时间。
查询结果是正确的,因为它完全按照您的要求执行:
如果根据左联接的定义没有匹配项,左联接将为您提供右 table 的空值。如果您 select 编辑了右侧 table 的更多列,则您将计算右侧 table 的空值,即 1.
所以 SAP 支持计数,您得到了正确的结果(不是您想要的结果)。
你要做的是select项单独统计。
注意:如果你这样做,sy-subrc 将永远为 0,即使没有项目。
这可能令人惊讶,但也是正确的,因为您得到的结果是 count=0。
好像DISTINCT是必须的,即COUNT( DISTINCT col )。
这适用于 7.52。
编辑:我在与 Suncatcher 讨论后删除了我的第一个查询,并在下面添加了更详细的答案。
当然DISTINCT不统计重复值,所以你可以统计主键所有列的串联(DISTINCT CONCAT( … ))。
先给大家看一下SCARR和SPFLI的内容,然后是最后的结果。
Table 疤痕:
CARRID
------
FJ
JL
LH
NG
Table SPFLI :
CARRID CONNID
------ ------
JL 0407
JL 0408
LH 0400
LH 0401
LH 0402
LH 2402
打开 SQL :
SELECT s~carrid, COUNT( DISTINCT CONCAT( p~carrid, p~connid ) ) AS count
FROM scarr AS s
LEFT OUTER JOIN spfli AS p ON s~carrid = p~carrid
GROUP BY s~carrid
WHERE s~carrid IN ('FJ','JL','LH','NG')
INTO TABLE @DATA(itab).
结果:
CARRID COUNT
------ ------
FJ 0
JL 2
LH 4
NG 0
这是 OpenSQL 的一个有趣的错误(或者可能是一个功能?),我在我的系统上确认了这一点。
解释在 implementation specifics of SQL engine by SAP:
When passed to data objects, null values are transformed to
type-dependent initial values
因此,并非 SAP DB 数据库字段中的所有空值都是空值,SAP 通常将这些空值视为有效值。
我在带有字段 EKGRP
的 MARA/MARC 表上测试了这个用例,并确认 COUNT
在我的数据上表现得很奇怪,当 EKGRP
为空或有初始值。
我的建议:比较 all 可能 empty/NULL values/variants 可以包含您的比较字段(在您的情况下为 item-key
)并检查它在 JOIN ON
条件 (!) 中而不是在 WHERE
子句中。
看样例:
SELECT mara~matnr, COUNT( DISTINCT marc~ekgrp ) AS count
FROM mara
LEFT OUTER JOIN marc
ON mara~matnr = marc~matnr
AND marc~ekgrp IS NOT NULL
AND marc~ekgrp NE ''
AND marc~ekgrp NE '000'
GROUP BY mara~matnr, marc~ekgrp
INTO TABLE @DATA(tab).
总而言之,这是高度依赖于数据库和字段类型的,所以这里没有简单的秘诀。 SAP 写道:
However, depending on the database system, empty strings can also be
displayed as null values.
是否可以count
left join
的记录?我想查看 count
return 实际加入的记录(包括 0
如果什么都没有加入)。
像下面这样的连接在我使用的其他形式的 SQL 中工作,但 OpenSQL 似乎不支持 count([column])
:
select header~key, count(item~key)
from header left join item on header~key = item~header_key
group by header~key.
我知道以下查询有效,但是 如果没有 items
与 header 连接,计数仍为 1 而不是 0:
select header~key, count(*) from header left join item group by header~key.
目前,我已在需要时使用 abap(loop
和 loop at
加上 group
)进行计数。
在我当前的场景中,我正在处理交易数据,与我以前的项目相比,这是巨大的,额外的循环会大大增加处理时间。
查询结果是正确的,因为它完全按照您的要求执行:
如果根据左联接的定义没有匹配项,左联接将为您提供右 table 的空值。如果您 select 编辑了右侧 table 的更多列,则您将计算右侧 table 的空值,即 1.
所以 SAP 支持计数,您得到了正确的结果(不是您想要的结果)。
你要做的是select项单独统计。 注意:如果你这样做,sy-subrc 将永远为 0,即使没有项目。
这可能令人惊讶,但也是正确的,因为您得到的结果是 count=0。
好像DISTINCT是必须的,即COUNT( DISTINCT col )。
这适用于 7.52。
编辑:我在与 Suncatcher 讨论后删除了我的第一个查询,并在下面添加了更详细的答案。
当然DISTINCT不统计重复值,所以你可以统计主键所有列的串联(DISTINCT CONCAT( … ))。
先给大家看一下SCARR和SPFLI的内容,然后是最后的结果。
Table 疤痕:
CARRID
------
FJ
JL
LH
NG
Table SPFLI :
CARRID CONNID
------ ------
JL 0407
JL 0408
LH 0400
LH 0401
LH 0402
LH 2402
打开 SQL :
SELECT s~carrid, COUNT( DISTINCT CONCAT( p~carrid, p~connid ) ) AS count
FROM scarr AS s
LEFT OUTER JOIN spfli AS p ON s~carrid = p~carrid
GROUP BY s~carrid
WHERE s~carrid IN ('FJ','JL','LH','NG')
INTO TABLE @DATA(itab).
结果:
CARRID COUNT
------ ------
FJ 0
JL 2
LH 4
NG 0
这是 OpenSQL 的一个有趣的错误(或者可能是一个功能?),我在我的系统上确认了这一点。
解释在 implementation specifics of SQL engine by SAP:
When passed to data objects, null values are transformed to type-dependent initial values
因此,并非 SAP DB 数据库字段中的所有空值都是空值,SAP 通常将这些空值视为有效值。
我在带有字段 EKGRP
的 MARA/MARC 表上测试了这个用例,并确认 COUNT
在我的数据上表现得很奇怪,当 EKGRP
为空或有初始值。
我的建议:比较 all 可能 empty/NULL values/variants 可以包含您的比较字段(在您的情况下为 item-key
)并检查它在 JOIN ON
条件 (!) 中而不是在 WHERE
子句中。
看样例:
SELECT mara~matnr, COUNT( DISTINCT marc~ekgrp ) AS count
FROM mara
LEFT OUTER JOIN marc
ON mara~matnr = marc~matnr
AND marc~ekgrp IS NOT NULL
AND marc~ekgrp NE ''
AND marc~ekgrp NE '000'
GROUP BY mara~matnr, marc~ekgrp
INTO TABLE @DATA(tab).
总而言之,这是高度依赖于数据库和字段类型的,所以这里没有简单的秘诀。 SAP 写道:
However, depending on the database system, empty strings can also be displayed as null values.