2013-01-16 127 views
2

国名我有一个具有以下字段的表:集团通过在MySQL

id, country_id, name, n_ocurrences 
1 uk   John  3 
2 us   John  4 
3 uk   Matt  0 
4 us   Matt  5 

我将如何去得到结果的列表,将是这样的:

name uk us total_ocurrences 
John 3  4   7 
Matt 0  5   5 

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

编辑:请注意,表大于这个,实际上我正在做一个带有country_ids列表的WHERE。

由于

+0

如果国家的名单是未知的,你可以使用预处理语句和存储过程的组合来做到这一点,但坦率地说,做一个简单的GROUP BY并处理应用程序级别的显示会更容易。 – Strawberry

+0

一群人会给每个s_name只有一行...我会失去每个国家的价值观,对吧? –

回答

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 

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; 

SQL Fiddle with Demo

均可以得到结果:

| NAME | OCCURRENCES_UK | OCCURRENCES_US | TOTAL_OCURRENCES | 
------------------------------------------------------------- 
| John |    3 |    4 |    7 | 
| Matt |    0 |    5 |    5 | 
+0

感谢您的回答。我应该说,桌子的内容只是一个例子。我有更多的国家,我不知道我想在哪里做什么,所以我不能“硬编码”country_id ='英国'。抱歉。我编辑了我的问题。 –

+0

@HommerSmith当你编辑你的问题时,我正在使用准备好的语句来处理动态版本。看到我的附加查询。 – Taryn

+0

这会很好。但是我无法在我正在开发的框架中做好准备。这会是一个更简单的方法吗? –