全联接中的行数 (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 中的行。

当您使用子查询时,实际上是在过滤掉行。