【问题标题】:Setting column values as column names in the SQL query result将列值设置为 SQL 查询结果中的列名
【发布时间】:2012-10-09 20:47:59
【问题描述】:

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

id    col1     col2
----------------------
0      name    ax
0      name2   bx
0      name3   cx
1      name    dx
1      name2   ex
1      name3   fx                

如果您看到 id = 0,name 的值为 ax,name2 为 bx,name3 为 cx。 与其将其显示为行,不如将列显示为 id、name、name2、name3。 现在我希望查询的结果如下所示:

id   name    name2     name3
0    ax      bx         cx
1    dx      ex         fx

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

【问题讨论】:

  • 如果您避免将列名存储为数据并使用它们是实际列名的表,那么这当然会更容易。 qquerying 困难是使用 EAV 结构的一大缺点,以及性能。你真的需要那种结构吗?你能重新设计吗?

标签: mysql sql pivot


【解决方案1】:

这是通过数据透视表完成的。按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

Here's a working sample

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

【讨论】:

  • 这是一个非常快速的响应,非常感谢您....这就像一个魅力,这就是我所期待的。太棒了...感谢您的快速帮助。
  • 如何通过pivot操作符实现?
【解决方案2】:

您尝试做的是PIVOT MySQL 没有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

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

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;

SQL Fiddle with Demo

【讨论】:

    【解决方案3】:
    select id,
        max(if(tablename.columnname = 'name',tablename.columnname,null)) as namealise,
        max(if(tablename.columnname = 'name1',tablename.columnname,null)) as namealise1 
    from table1, table2 
    where table1.id = table2.id 
    group by table1.id 
    order by table1.id
    

    【讨论】:

    • 解释一下会很有帮助。并考虑使用code formatting 以提高可读性。
    猜你喜欢
    • 2012-05-07
    • 1970-01-01
    • 1970-01-01
    • 2021-02-06
    • 1970-01-01
    • 2021-12-26
    • 2011-04-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多