0

我在数据库中有两列名称和年份的数据。像这样的东西,

name | year
-----------
tim  | 2001
ron  | 2002
tim  | 2003
ron  | 2005
tim  | 2004
pol  | 2002
pol  | 2001
tim  | 2003
pol  | 2004
tim  | 2002

我想输出这样的结果矩阵。

      tim | pol | ron
2001   1  |  1  |  0
2002   1  |  1  |  1
2003   2  |  0  |  0
2004   1  |  1  |  0
2005   0  |  0  |  1

蒂姆 | 波尔 | ron 是根据累计和降序排列的,即 tim(5), pol(3), ron(2)。

数据不限于 tim,pol,ron。可以有 n 个不同的名称。

4

3 回答 3

5
SELECT
  year,
  SUM(name='tim') tim,
  SUM(name='pol') pol,
  SUM(name='ron') ron
FROM
  yourtable
GROUP BY
   year

在此处查看小提琴。

编辑:如果您需要动态查询,因为值的确切数量可能会有所不同,您可以使用如下准备好的语句:

SELECT
  CONCAT('SELECT year,',
  GROUP_CONCAT(sums),
  ' FROM yourtable GROUP BY year')
FROM (
SELECT CONCAT('SUM(name=\'', name, '\') AS `', name, '`') sums
FROM yourtable
GROUP BY name
ORDER BY COUNT(*) DESC
) s
INTO @sql;

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

小提琴在这里

于 2013-07-01T08:37:32.787 回答
0

您可以执行以下操作,然后在表示层转置它。

SELECT yourtable.year, Hits.name, Hits.hit
FROM yourtable
LEFT JOIN (SELECT
 year, name, count(*) as hit
FROM
  yourtable
GROUP BY
   year, name) AS Hits ON yourtable.year = Hits.year
GROUP BY yourtable.year, yourtable.name

它缺少无命中,即那些不属于某一年的名称,即你不会看到任何0

于 2013-07-01T08:54:05.483 回答
0

虽然 fthiella 的方法是构建数据透视表的最常用方法,但您可能想尝试这个查询,在大多数情况下更快:

SELECT
  years.year,
  COALESCE(tim.c, 0) AS tim,
  COALESCE(pol.c, 0) AS pol,
  COALESCE(pol.c, 0) AS ron
FROM (SELECT year FROM yourtable GROUP BY year) AS years
LEFT JOIN (
  SELECT COUNT(name) AS c, year FROM yourtable WHERE name = 'tim' GROUP BY year
) AS tim ON (tim.year = years.year)
LEFT JOIN (
  SELECT COUNT(name) AS c, year FROM yourtable WHERE name = 'pol' GROUP BY year
) AS pol ON (pol.year = years.year)
LEFT JOIN (
  SELECT COUNT(name) AS c, year FROM yourtable WHERE name = 'ron' GROUP BY year
) AS ron ON (ron.year = years.year)
GROUP BY years.year;

这写起来有点痛苦,而且要表现得好,它需要两个索引:

  • 按此顺序在用作列和行判别符的两个字段上的双列索引(即,在您的情况下,(name, year)按此顺序)
  • 行判别式的索引(即在您的情况下, on (year)

但是结果越大(更多的行或更多的列或两者),与通常的方法相比,它的执行速度就越快。如果有人想玩它,我在这里发布了一些示例数据。相应的查询在这里

于 2013-07-01T10:08:19.103 回答