在SQL查询结果中将列值设置为列名

rav*_*avi 11 mysql sql pivot

我想读一个表,其中的值将是sql查询结果的列名.例如,我有table1作为..

id    col1     col2
----------------------
0      name    ax
0      name2   bx
0      name3   cx
1      name    dx
1      name2   ex
1      name3   fx                
Run Code Online (Sandbox Code Playgroud)

如果你看到id = 0,名称的值为ax和名称2 - bx和name3 = cx而不是这是行,那么将列更容易显示为id,name,name2,name3现在我想要查询的结果看起来像这样

id   name    name2     name3
0    ax      bx         cx
1    dx      ex         fx
Run Code Online (Sandbox Code Playgroud)

有人可以帮我实现这个目标吗?

Mic*_*ski 15

这是通过数据透视表完成的.通过分组id,您可以CASE为要在列中捕获的每个值发出语句,并使用类似MAX()聚合的内容来消除空值并折叠为一行.

SELECT
  id,
  /* if col1 matches the name string of this CASE, return col2, otherwise return NULL */
  /* Then, the outer MAX() aggregate will eliminate all NULLs and collapse it down to one row per id */
  MAX(CASE WHEN (col1 = 'name') THEN col2 ELSE NULL END) AS name,
  MAX(CASE WHEN (col1 = 'name2') THEN col2 ELSE NULL END) AS name2,
  MAX(CASE WHEN (col1 = 'name3') THEN col2 ELSE NULL END) AS name3
FROM
  yourtable
GROUP BY id
ORDER BY id
Run Code Online (Sandbox Code Playgroud)

这是一个工作样本

注意:这仅适用于有限且已知数量的可能值col1.如果可能值的数量未知,则需要在循环中动态构建SQL语句.


Tar*_*ryn 7

您尝试做的是PIVOTMySQL没有PIVOT函数,因此您可以使用CASE和聚合函数复制它.

如果您有已知数量的列,则可以使用静态版本并对值进行硬编码.与此类似(请参阅SQL Fiddle with demo):

select id,
  max(case when col1='name' then col2 end) name,
  max(case when col1='name2' then col2 end) name2,
  max(case when col1='name3' then col2 end) name3
from yourtable
group by id
Run Code Online (Sandbox Code Playgroud)

但是如果您有不知数量的列,那么您可以使用预准备语句并动态创建它:

SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'max(case when col1 = ''',
      col1,
      ''' then col2 end) AS ',
      col1
    )
  ) INTO @sql
FROM yourtable;

SET @sql = CONCAT('SELECT id, ', @sql, ' 
                  FROM yourtable 
                  GROUP BY id');

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

请参阅SQL Fiddle with Demo