MySQL,对id为相同的多行进行分组

时间:2012-10-23 08:30:58

标签: php mysql sql

我继承了一个可爱的架构,它有三个字段:id, field_name, field_value。现在您可以看到它是如何工作的,对于通过CMS添加的每个字段,它都被添加为新行,而id值不是唯一的。

但是每个字段不是一个单独的实体,它们实际上应该按id(它引用已提交的表单的实例)进行分组。作为旁注,我有兴趣知道可以调用这种模式模式吗?

//example db contents
1    name        Joe Blogs
1    email       joe@example.com
1    programme   sport
2    name        Dave
2    email       dave@example.com
2    programme   art

当然,我真的希望使用一个查询来获取按id字段分组的选定字段。输出为array( id => array( 'field' => 'value' , 'field' => 'value' ) )

通常我会执行以下操作,但我想知道是否有一种纯SQL方法可以做到这一点,切断循环并在底部进行处理。

$existing = new stdClass;
$sql = "SELECT 'id','field_name','field_value'
                FROM table_name";
$results = $wpdb->get_results( $sql, ARRAY ); //using wordpress btw
        foreach ( $results as $k=>$r )
            $existing[$r['id']][$k] = $r;

1 个答案:

答案 0 :(得分:5)

您可以使用聚合函数和大小写来旋转值

SELECT  ID,
        MAX(CASE WHEN type = 'name' THEN value ELSE NULL end) Name,
        MAX(CASE WHEN type = 'email' THEN value ELSE NULL end) email,
        MAX(CASE WHEN type = 'programme' THEN value ELSE NULL end) programme
FROM table1
GROUP BY ID

SQLFiddle Demo

或将来,如果您计划在不更改查询的情况下添加其他类型,则可以使用预准备语句,

SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'MAX(CASE WHEN type = ''',
      type,
      ''' then value ELSE NULL end) AS ',
      type
    )
  ) INTO @sql
FROM table1;

SET @sql = CONCAT('SELECT  ID, ', @sql, ' 
                   FROM table1 
                   GROUP BY ID');

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

SQLFiddle Demo