按MySQL中的国家/地区分组

Hom*_*ith 2 mysql pivot group-by

我有一个包含以下字段的表:

id, country_id, name, n_ocurrences
1   uk          John     3
2   us          John     4
3   uk          Matt     0
4   us          Matt     5
Run Code Online (Sandbox Code Playgroud)

我将如何获得如下所示的结果列表:

name   uk    us   total_ocurrences
John   3     4            7
Matt   0     5            5
Run Code Online (Sandbox Code Playgroud)

现在我在直接PHP处理结果中这样做,但我想知道我是否可以在MySQL中执行此操作.

编辑:请注意,表格大于此,实际上我正在使用country_ids列表进行WHERE.

谢谢

Tar*_*ryn 6

这种类型的数据转换是一个支点.在MySQL中生成此结果,您将使用带有case表达式的聚合函数:

select name,
  sum(case when country_id = 'uk' then n_ocurrences else 0 end) occurrences_uk,
  sum(case when country_id = 'us' then n_ocurrences else 0 end) occurrences_us,
  sum(n_ocurrences) total_ocurrences
from yourtable
group by name
Run Code Online (Sandbox Code Playgroud)

请参阅SQL Fiddle with Demo.

如果你知道country_id提前的值,上面的版本很有用,但如果你不知道,那么你可以使用预准备语句来生成动态sql:

SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'sum(case when country_id = ''',
      country_id,
      ''' then n_ocurrences end) AS occurrences_',
      country_id
    )
  ) INTO @sql
FROM yourtable;

SET @sql = CONCAT('SELECT name, ', @sql, ' ,
                      sum(n_ocurrences) total_ocurrences
                  FROM yourtable 
                  GROUP BY name');

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
Run Code Online (Sandbox Code Playgroud)

请参阅SQL Fiddle with Demo

两者都给出了结果:

| NAME | OCCURRENCES_UK | OCCURRENCES_US | TOTAL_OCURRENCES |
-------------------------------------------------------------
| John |              3 |              4 |                7 |
| Matt |              0 |              5 |                5 |
Run Code Online (Sandbox Code Playgroud)