【问题标题】:SQL: How to compare tables, i.e. count rows in joined tables?SQL:如何比较表,即计算连接表中的行数?
【发布时间】:2018-08-21 18:59:29
【问题描述】:

我正在加入两个表,我想获得一些描述该操作的简单统计信息,即:

  • 我在每个表中总共有多少行
  • 其中有多少人将加入
  • 将留下多少未加入

我确信必须有一些智能且简单的方法来即时获取所有信息 - 无需创建和计算额外的标志/变量,也无需长长的查询序列。

如果有这样的解决方案来连接两个以上的数据集,那就太好了 - 当 3 个表格 时,可以轻松计算下图中可见的 7 组记录进行比较。

我目前正在从 SAS 查询,但在使用 Oracle 和 MS SQL 时我经常遇到同样的问题 - 我正在寻找一些与 dbms 无关的解决方案。

【问题讨论】:

  • 请提供一些非常有用的示例数据
  • 你说 dbms-agnostic,但标记 MySQL。
  • @D-Shih - 我两边都有数千条记录。第一个是参考 - 整个活跃的投资组合。第二个包含计算了一些参数的产品。我想完全外连接会在两边留下一些未连接的记录(部分活动投资组合没有计算参数,以及为不再在活动投资组合中的产品计算的参数)。我想知道关系的形状。
  • @jarlh - 你知道 MySQL 的解决方案吗?很高兴知道,我希望我们能够针对另一个 dbms 进行调整,甚至使其与 dbms-agnostic 无关。

标签: mysql sql join sas dataset


【解决方案1】:

在使用 SAS PROC SQL 时,最有用的选项之一是 verbose 。例如:

%macro create_data(num, min, max);
  /* Creates sample datasets */
  DATA have&num.;
      do i=&min. to &max.;
          ID = i; OUTPUT;
      end; DROP i;
  RUN;
%mend create_data;

%create_data(1,1,10);
%create_data(2,5,15);
%create_data(3,9,100);

PROC SQL verbose;
    /* Sample join */
    CREATE table want as
        SELECT have1.ID as ID1, have2.ID as ID2, have3.ID as ID3
        FROM have1
        FULL JOIN have2
            on have1.ID=have2.ID
        RIGHT JOIN have3
            on have3.ID=have1.ID;
QUIT;

将在您的 SAS 日志中打印以下内容:

Data Set WORK.HAVE1 is num=1 and tag=0001. NOBS=10, lrecl=8.
Data Set WORK.HAVE2 is num=2 and tag=0002. NOBS=11, lrecl=8.
Data Set WORK.HAVE3 is num=3 and tag=0004. NOBS=92, lrecl=8.
NOTE: Table WORK.WANT created, with 92 rows and 3 columns.

这对于查看连接行为非常有用,尤其是对于多个数据集。

如果您在 SAS 之外工作并寻找通用 SQL 解决方案,我认为您最好(也是最快)的解决方案是查询计数。例如,从上面的选择中:

* how many rows I have in total in each of tables ;
SELECT count(*) from have1;
SELECT count(*) from have2;
SELECT count(*) from have3;
* how many of them are joined ;
SELECT count(*) from want;
* how many will be left unjoined ;
SELECT count(*) from want where missing(ID1) or missing(ID2) or missing(ID3);

在不了解具体情况的情况下很难给您额外的建议。 SQL 对此没有标准解决方案的部分原因是,不同类型的连接在本质上彼此之间存在很大差异。

【讨论】:

    【解决方案2】:

    您可以通过以下方式获得跨表的键分布:

    select in1, in2, in3, count(*) as numkeys, min(key) as key1, max(key) as key2
    from (select key, sum(in1) as in1, sum(in2) as in2, sum(in3) as in3
          from ( (select key, count(*) as in1, 0 as in2, 0 as in3 from table1 group by key
                 ) union all
                 (select key, 0 as in1, count(*) as in2, 0 as in3 from table2 group by key
                 ) union all
                 (select key, 0 as in1, 0 as in2, count(*) as in3 from table3 group by key
                 ) 
                ) t123
          group by key
         ) k
    group by in1, in2, in3;
    

    所有值都非零的行是内部连接返回的行。如果“key”是主键,那么所有的值都是 0 或 1(计数除外)。

    【讨论】:

    • 谢谢。漂亮而简洁的解决方案导致小表:\\\ in1 | in2 | in3 |数字键 \\\ 0 | 0 | 1 |结果 \\\ 0 | 1 | 1 |结果 \\\ 1 | 0 | 1 |结果 \\\ 1 | 1 | 1 |结果 \\\ 不是我正在寻找的所有答案,但它的简单性令人印象深刻,非常感谢! [编辑:废话,不允许在 cmets 中换行...]
    猜你喜欢
    • 2014-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-12
    • 1970-01-01
    • 2013-08-25
    相关资源
    最近更新 更多