连接和分组以等于两个表

时间:2019-12-06 20:26:29

标签: sql sql-server

我试图尽可能减少此问题。我有两个共享一些ID的表(在其他列中)

 id       id
----     ----
  1        1
  1        1
  2        1
           2
           2

首先,我可以将每个表解析为一个简单的计数,其中包含每个ID的数量:

select id, count(*) from tbl1 group by id
select id, count(*) from tbl2 group by id

id | tbl1-count    id | tbl2-count
---------------    ---------------
 1       2          1         3
 2       1          2         2

但是然后我很茫然,我试图得到以下输出,该输出显示每个id从tbl2的计数,除以相同id从tbl1的计数:

id | count of id in tbl2 / count of id in tbl1
==========
 1 |  1.5
 2 |   2

到目前为止,我已经知道了:

select tbl1.Id, tbl2.Id, count(*)
from tbl1 
join tbl2 on tbl1.Id = tbl2.Id
group by tbl1.Id, tbl2.Id

这给了我...好吧...说实话,这远远超出了我的需求!我正在尝试count(tbl1.Id),count(tbl2.Id),但是得到相同的乘数(因为我想加入吗?)-我无法将各个表示形式放入可以进行除法的各个列中

3 个答案:

答案 0 :(得分:1)

您可以聚合子查询,然后进行join

select t1.id, t2.cnt * 1.0 / t1.cnt
from (select id, count(*) as cnt
      from tbl1
      group by id
     ) t1 join
     (select id, count(*) as cnt
      from tbl2
      group by id
     ) t2
     on t1.id = t2.id

答案 1 :(得分:1)

假设您的预期结果是错误的,那么我将这样做:

CREATE TABLE T1 (ID int);
CREATE TABLE T2 (ID int);
GO

INSERT INTO T1 VALUES(1),(1),(2);
INSERT INTO T2 VALUES(1),(1),(1),(2),(2);
GO

SELECT T1.ID AS OutID,
       (T2.T2Count * 1.) / COUNT(T1.ID) AS OutCount --Might want a CONVERT to a smaller scale and precision decimal here
FROM T1
     CROSS APPLY (SELECT T2.ID, COUNT(T2.ID) AS T2Count
                  FROM T2
                  WHERE T2.ID = T1.ID
                  GROUP BY T2.ID) T2
GROUP BY T1.ID,
         T2.T2Count;

GO
DROP TABLE T1;
DROP TABLE T2;

答案 2 :(得分:1)

这考虑了您对表的命名-来自tbl2的查询需要首先进行,因此结果将包括来自tbl2的所有记录。 LEFT JOIN将包含第一个查询的所有结果,但仅将tbl1中存在的那些结果联接在一起。 (或者,您可以在第一个查询中同时使用FULL OUTER JOIN或UNION两个结果。)我还添加了一个IIF,以便在tbl1中没有记录的情况下为您提供一个选项(除以null仍然会产生null,但是您可以做你想要的)。

将计数强制转换为十进制,以便比率将返回为十进制。您可以根据需要调整精度。

SELECT tb2.id, tb2.table2Count, tb1.table1Count,
    IIF(ISNULL(tb1.table1Count, 0) != 0, tb2.table2Count / tb1.table1Count, null) AS ratio
FROM (
    SELECT id, CAST(COUNT(1) AS DECIMAL(18, 5)) AS table2Count
    FROM tbl2
    GROUP BY id
    ) AS tb2
LEFT JOIN (
    SELECT id, CAST(COUNT(1) AS DECIMAL(18, 5)) AS table1Count
    FROM tbl1
    GROUP BY id
    ) AS tb1 ON tb1.id = tb2.id

(具有LEFT JOIN的子查询将使查询优化器可以确定如何生成结果,并且通常会优于CROSS APPLY,因为它对每条记录执行计算。)