简体   繁体   English

MySQL,将ID相同的多行分组

[英]MySQL, grouping multiple rows where the id is the same

I have inherited a lovely schema which has three fields: id, field_name, field_value . 我继承了一个可爱的架构,其中包含三个字段: id, field_name, field_value Now you can probably see how this is going to work, for each field that is added via the CMS it is added as a new row, while the id value is NOT unique. 现在您可能已经看到了它是如何工作的,对于通过CMS添加的每个字段,它都作为新行添加,而id值不是唯一的。

But each field is not an individual entity, they should in fact be grouped by the id (which references the instance of the form that was submitted). 但是每个字段都不是一个单独的实体,实际上它们应该按ID(引用已提交表单的实例)进行分组。 As a side note I'd be interested to know what this schema pattern might be called? 附带说明一下,我很想知道该模式可能被称为什么?

//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

And of course I really want to be using one query to get selected fields grouped by the id field. 当然,我真的很想使用一个查询来获取按ID字段分组的所选字段。 Output as array( id => array( 'field' => 'value' , 'field' => 'value' ) ) etc 输出为array( id => array( 'field' => 'value' , 'field' => 'value' ) )等等

Typically I'd do the below, but I'd like to know if there is a pure SQL way to do this, cutting out the loop and processing at the bottom. 通常,我会执行以下操作,但是我想知道是否有一种纯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;

You can use aggregate function and case to pivot the values, 您可以使用聚合函数和大小写来透视值,

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 SQLFiddle演示

or in the future if you are planning to add another type without altering the query, you can use prepared statements, 或者将来,如果您打算添加另一种类型而不更改查询,则可以使用准备好的语句,

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 SQLFiddle演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM