mysql - 如何在额外列中显示值的计数

时间:2013-11-24 03:14:13

标签: mysql sql

想象一下,我们有一个这样的表:

id  value
 1      a
 2      b
 3      a
 4      a
 5      b

像这样查询

SELECT * , COUNT( * )
FROM test
GROUP BY value

给我们一个这样的表:

id  value COUNT(*)
 1      a       3
 2      b       2

告诉我们表格中有三个'a'和两个'b'。

问题是:是否可以进行查询(没有嵌套的SELECT),这将产生类似

的表
id  value count_in_col
 1      a            3
 2      b            2
 3      a            3
 4      a            3
 5      b            2

目标是避免折叠列并将整列中“value”元素的数量添加到每一行。

4 个答案:

答案 0 :(得分:2)

我认为没有子查询可以计算不同值的出现次数:

SELECT a.*,b.valCount
FROM test a
INNER JOIN 
(
  SELECT value,COUNT(*) AS valCount
  FROM test
  GROUP BY value
) b
ON b.value = a.value
ORDER BY a.id;

sqlfiddle demo

答案 1 :(得分:2)

是的,可以仅使用一个SELECT关键字返回指定的结果集。

 SELECT t.id
      , t.value
      , COUNT(DISTINCT u.id) AS count_in_col
   FROM mytable t
   JOIN mytable u
     ON u.value = t.value
  GROUP
     BY t.id

设置测试用例:

 CREATE TABLE `mytable` (`id` INT, `value` VARCHAR(1));
 INSERT INTO `mytable` VALUES (1,'a'), (2,'b'),(3,'a'),(4,'a'),(5,'b');

返回:

    id  value   count_in_col  
------  ------  --------------
     1  a                    3
     2  b                    2
     3  a                    3
     4  a                    3
     5  b                    2

注:

这假设id在表中是唯一的,这将由主键或唯一键约束强制执行。

就性能而言,取决于基数,索引...... ON (value,id)可能会提高效果。

这种方法(使用JOIN来匹配value列上的行)确实有可能产生一个非常大的中间结果集,如果在value上存在匹配的“很多”行。例如,如果有1,000行value='a',则这些行的中间结果集将为1,000 * 1,000 = 1,000,000行。

添加谓词(在ON子句中)也可以提高性能,但减少中间结果中的行数。

    ON u.value = t.value
   AND u.id >= t.id

(没有真正的魔力;“技巧”是使用COUNT(DISTINCT id)来避免同一id值被多次计算。)

答案 2 :(得分:0)

您需要使用子查询对值进行分组并进行计数。然后你只需要在值字段上加入该子查询。

SELECT test.id, test.value, t2.val_count 
FROM test INNER JOIN 
  (SELECT value, COUNT(value) AS val_count FROM test GROUP BY value) AS t2
  ON test.value = t2.value;

http://sqlfiddle.com/#!2/c8578/7

编辑:我刚看到您在不使用嵌套查询的情况下要求答案。我不认为这是可能的,但如果我找到办法,我会修改我的答案。

答案 3 :(得分:0)

这是简单(和更快)的SQL,但要准确打印您想要的内容,客户端程序应该解析GROUP_CONCAT的输出

SELECT GROUP_CONCAT(id), value, COUNT( * )
FROM test
GROUP BY value;