【问题标题】:MySQL Counting unique values over two columns and joining those counts for each columnMySQL计算两列上的唯一值并为每列加入这些计数
【发布时间】:2012-11-06 08:48:25
【问题描述】:

我有一个这样设置的表:

  +----+-------+-------+
  | 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; 

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

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

【问题讨论】:

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


    【解决方案1】:

    我假设您的案例可能比您在数据中显示的要多。你可以在 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 中名称的另一个类似派生故事。

    【讨论】:

    • 谢谢,我一直在努力解决这个问题。您的解释清晰简洁。
    【解决方案2】:

    试试这个:

    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

    【讨论】:

      【解决方案3】:
      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 的回答。

      【讨论】:

        【解决方案4】:

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

        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中的唯一值,所以我将col2的计数设置为0。第二个计算col2中的唯一值,所以我将0设置为col1的计数。联合查询将这两个查询组合在一起,因此我们现在只需对结果进行分组和求和。由于不涉及任何连接,我认为这个解决方案应该很快。

        【讨论】:

          猜你喜欢
          • 2014-04-07
          • 1970-01-01
          • 1970-01-01
          • 2016-09-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多