MySQL在两列上计算唯一值,并为每列连接这些计数

时间:2012-11-18 01:48:05

标签: mysql sql left-join outer-join jointable

我有一个像这样设置的表:

  +----+-------+-------+
  | id | col1  | col2  |
  +----+-------+-------+
  |  1 | John  | Mike  |
  |  2 | Mike  | John  |
  |  3 | Marty | John  |
  |  4 | Walt  | Marty |
  |  5 | Walt  | Mike  |
  +----+-------+-------+

我基本上想要计算col1和col2中的唯一值,并将它们与适当的唯一值一起显示。问题是col1不一定包含col2所具有的所有相同名称,反之亦然。我希望得到这样的设置:

 +-------+-------+------+
 | names | col1  | col1 |
 +-------+-------+------+
 | John  |     1 |    2 |
 | Marty |     1 |    1 |
 | Mike  |     1 |    2 |
 | Walt  |     2 | NULL |
 +-------+-------+------+

我可以使用以下方法单独选择这些值:

  SELECT col1, count(col1) as count FROM example GROUP BY col1; 

OR

  SELECT col2, count(col2) as count FROM example GROUP BY col2;

但是我很难理解我如何将这两个计数加在一起,特别是因为这里的值“Walt”没有出现在col2中。

4 个答案:

答案 0 :(得分:4)

我假设您的案例可能比您在数据中显示的案件多。您可以在col1中使用NULL,您可以将名称仅发生在col1中或仅发生在col2中等。

SELECT a.name, c1.`count`, c2.`count`
FROM (SELECT col1 AS name FROM `Table` UNION SELECT col2 FROM `Table`) a
LEFT JOIN (SELECT col1, COUNT(*) AS `count` FROM `Table` GROUP BY col1) c1 
  ON a.name = c1.col1
LEFT JOIN (SELECT col2, COUNT(*) AS `count` FROM `Table` GROUP BY col2) c2 
  ON a.name = c2.col2;

说明:
派生表a是出现在任一列中的所有名称的并集。 然后再创建两个派生表,每个表都有一个来自col1的每个名称,以及它出现次数的计数,然后是另一个类似于col2中名称的派生故事。

答案 1 :(得分:1)

试试这个:

SELECT 
  t1.col1, 
  count(t2.col2), 
  COUNT(t1.col2) 
FROM table1 t1
LEFT JOIN 
(
   SELECT col2 
   FROM Table1
) t2 ON t1.col1 = t2.col2
GROUP BY t1.col1;

SQL Fiddle Demo

答案 2 :(得分:1)

select coalesce(a.col1,b.col2) names, a.c col1, b.c col2 from
(select col1, count(*) c from table1 group by col1) a
left outer join
(select col2, count(*) c from table1 group by col2) b
on a.col1 = b.col2;

实际上需要full outer join来包含仅存在于col2中的名称 - 因为MySQL不支持完全外连接,所以必须首先将它们组合在一起,如Bill的答案所示。

答案 3 :(得分:1)

这也可以是一个解决方案:

select names, sum(totalc1), sum(totalc2)
from
  (select col1 as names, count(col1) as totalc1, 0 as totalc2
   from your_table group by col1
   union
   select col2 as names, 0 as totalc1, count(col2) as totalc2
   from your_table group by col2) t
group by names

我只是将您的两个原始查询合并为一个。

第一个计算col1中的唯一值,所以我将0设置为col2的计数。第二个计算col2中的唯一值,所以我将0设置为col1的计数。联合查询将这两个查询组合在一起,因此我们现在只需分组并对结果求和。由于没有涉及联接,我认为这个解决方案应该很快。