全联接中的行数 (DB2 - SQL)
Number of Rows in a Full Join (DB2 - SQL)
我是 运行 DB2/SQL - FULL JOIN 查询。
PROC SQL;
CONNECT TO db2 AS db1 (USER=&dpwuscod. PASSWORD=&dpwpwcod. DATABASE=&dpwdbnam.);
CREATE TABLE result3 AS
SELECT *
FROM CONNECTION to db2
(
SELECT count(* ) as NbrCount
FROM a
FULL JOIN b
ON a.pk = b.pk
AND a.snap_dt='2015-08-31'
AND a.sys_num not in ('1234')
);
DISCONNECT FROM db2;
QUIT;
Table A 有 586,648 行。 Table B 有 2,384,874 行。
我期望 FULL Join 中的行数在 2,384,874(当 PK 完全重叠时)到 2,971,522(当两个表具有互斥 PK / 2,971,522 = 586,648 + 2,384,874 时)
然而,实际上,上述连接产生 NbrCount = 24,898,361。
关于为什么行数激增的任何指示?
因为有些 pk
有重复匹配项。这很容易找到:
select pk, count(*)
from a
group by pk
having count(*) > 1;
select pk, count(*)
from b
group by pk
having count(*) > 1;
当然,您可以限制使用过滤器的条件。
而且,也许您希望在 select
子句中包含 count(distinct coalesce(a.pk, b.pk))
。这将计算从每个 table 返回的行数,行上没有重复项。
@gordon-linoff ...我通过向上移动 a
上的 EOM/snap_dt 过滤器解决了这个问题。
PROC SQL;
CONNECT TO db2 AS db1 (USER=&dpwuscod. PASSWORD=&dpwpwcod. DATABASE=&dpwdbnam.);
CREATE TABLE dbt_info2 AS
SELECT *
FROM CONNECTION to db2
(
SELECT b.*,
coalesce(a.pk,b.pk) pk,
FROM ( SELECT p.pk,
FROM a p
WHERE p.snap_dt= &snap_dt.
AND p.sys_num NOT IN ('1234')
) a
FULL JOIN b
ON a.pk = b.pk );
DISCONNECT FROM db2;
QUIT;
但是,我认为这段代码在功能上等同于我的原始代码。显然不是,所以我试图了解 FULL JOIN 子集中的 ON 子句如何 table (以及它与内联 WHERE 子句有何不同 - 我理解它与最终 WHERE 子句有何不同)。
编辑:
评论太长了。
这在功能上与您的原始代码不同。 FULL OUTER JOIN
从两个 table 中获取匹配行以及从两个 table 中获取 all 行,其中 ON
子句不计算为真。因此,如果您在 ON
子句中添加条件,它实际上不会过滤您正在查看的 table 中的行。
当您使用子查询时,实际上是在过滤掉行。
我是 运行 DB2/SQL - FULL JOIN 查询。
PROC SQL;
CONNECT TO db2 AS db1 (USER=&dpwuscod. PASSWORD=&dpwpwcod. DATABASE=&dpwdbnam.);
CREATE TABLE result3 AS
SELECT *
FROM CONNECTION to db2
(
SELECT count(* ) as NbrCount
FROM a
FULL JOIN b
ON a.pk = b.pk
AND a.snap_dt='2015-08-31'
AND a.sys_num not in ('1234')
);
DISCONNECT FROM db2;
QUIT;
Table A 有 586,648 行。 Table B 有 2,384,874 行。
我期望 FULL Join 中的行数在 2,384,874(当 PK 完全重叠时)到 2,971,522(当两个表具有互斥 PK / 2,971,522 = 586,648 + 2,384,874 时)
然而,实际上,上述连接产生 NbrCount = 24,898,361。
关于为什么行数激增的任何指示?
因为有些 pk
有重复匹配项。这很容易找到:
select pk, count(*)
from a
group by pk
having count(*) > 1;
select pk, count(*)
from b
group by pk
having count(*) > 1;
当然,您可以限制使用过滤器的条件。
而且,也许您希望在 select
子句中包含 count(distinct coalesce(a.pk, b.pk))
。这将计算从每个 table 返回的行数,行上没有重复项。
@gordon-linoff ...我通过向上移动 a
上的 EOM/snap_dt 过滤器解决了这个问题。
PROC SQL;
CONNECT TO db2 AS db1 (USER=&dpwuscod. PASSWORD=&dpwpwcod. DATABASE=&dpwdbnam.);
CREATE TABLE dbt_info2 AS
SELECT *
FROM CONNECTION to db2
(
SELECT b.*,
coalesce(a.pk,b.pk) pk,
FROM ( SELECT p.pk,
FROM a p
WHERE p.snap_dt= &snap_dt.
AND p.sys_num NOT IN ('1234')
) a
FULL JOIN b
ON a.pk = b.pk );
DISCONNECT FROM db2;
QUIT;
但是,我认为这段代码在功能上等同于我的原始代码。显然不是,所以我试图了解 FULL JOIN 子集中的 ON 子句如何 table (以及它与内联 WHERE 子句有何不同 - 我理解它与最终 WHERE 子句有何不同)。
编辑:
评论太长了。
这在功能上与您的原始代码不同。 FULL OUTER JOIN
从两个 table 中获取匹配行以及从两个 table 中获取 all 行,其中 ON
子句不计算为真。因此,如果您在 ON
子句中添加条件,它实际上不会过滤您正在查看的 table 中的行。
当您使用子查询时,实际上是在过滤掉行。