MySQL列明智的类别计数

时间:2012-09-11 01:24:04

标签: mysql sql

我有一张表:

id name center1    center2   cnter3
1  abc  baroda     bhopal    chennai
2  pqr  amhedabad  Surat     kolkata
3  nml  bhopal     chennai   Surat
4  fts  baroda     Surat     Baroda

我想要一个结果像:

         center1 center2  center3
Baroda     2       0        1   
Ahmedabad  1       0        0
bhopal     1       1        0
chennai    0       1        1
Kolkatta   0       0        1
Surat      0       2        1.

2 个答案:

答案 0 :(得分:3)

这将需要一些子查询连接。首先,您需要从三列中获取所有不同的值,这将通过每列的UNION个查询来完成。

然后必须对三个子查询LEFT JOIN进行不同的列表,这三个子查询从三列中的每一列中提取每个值的计数。

最后,COALESCE()将NULL替换为0。

SELECT 
  allvalues.value,
  /* LEFT JOIN will result in NULL for non-existent values, so coalesce into 0 */
  COALESCE(c1.counts, 0) AS center1,
  COALESCE(c2.counts, 0) AS center2,
  COALESCE(c3.counts, 0) AS center3
FROM
  (
    /* UNIONs gets distinct vals from all columns */
    SELECT center1 AS value FROM yourtable
    UNION
    SELECT center2 AS value FROM yourtable
    UNION
    SELECT center3 AS value FROM yourtable
  ) AS allvalues
  /* LEFT JOIN the list of distinct possible values against a count per value for each column */
  LEFT JOIN (
    SELECT center1, COUNT(*) AS counts FROM yourtable GROUP BY center1
  ) c1 ON allvalues.value = c1.center1
  LEFT JOIN (
    SELECT center2, COUNT(*) AS counts FROM yourtable GROUP BY center2
  ) c2 ON allvalues.value = c2.center2
  LEFT JOIN (
    SELECT center3, COUNT(*) AS counts FROM yourtable GROUP BY center3
  ) c3 ON allvalues.value = c3.center3 

Here is a working demonstration,因为我想我今晚感觉更加慈善。

答案 1 :(得分:2)

我使用sqlfiddle将表格的文本表示转换为CREATE TABLE和INSERT INTO语句的序列:

CREATE TABLE CenterCodes
    (`id` int, `name` varchar(3), `center1` varchar(9), `center2` varchar(7), `center3` varchar(7))
;

INSERT INTO CenterCodes
    (`id`, `name`, `center1`, `center2`, `center3`)
VALUES
    (1, 'abc', 'baroda', 'bhopal', 'chennai'),
    (2, 'pqr', 'amhedabad', 'Surat', 'kolkata'),
    (3, 'nml', 'bhopal', 'chennai', 'Surat'),
    (4, 'fts', 'baroda', 'Surat', 'Baroda')
;

尝试以下查询。内部UNION为每个字符串值生成多行,每个集合中3列中的2列为NULL。然后,外部查询中的聚合SUM()消除了这些NULL,将行集折叠为每个字符串值一行。

SELECT
  centername,
  SUM(CASE WHEN centername = center1 THEN 1 ELSE 0 END) AS center1,
  SUM(CASE WHEN centername = center2 THEN 1 ELSE 0 END) AS center2,
  SUM(CASE WHEN centername = center3 THEN 1 ELSE 0 END) AS center3
FROM (
  SELECT
    center1 AS centername,
    center1,
    NULL AS center2,
    NULL AS center3
  FROM CenterCodes
  UNION ALL
  SELECT
    center2 AS centername,
    NULL AS center1,
    center2,
    NULL AS center3
  FROM CenterCodes
  UNION ALL
  SELECT
    center3 AS centername,
    NULL AS center1,
    NULL AS center2,
    center3
  FROM CenterCodes
) AS Centers
GROUP BY centername;