Mysql,将数据从长/高重塑为宽

Mysql,将数据从长/高重塑为宽,sql,mysql,statistics,reshape,Sql,Mysql,Statistics,Reshape,我在mysql表中有长/高格式(如下所述)的数据,希望将其转换为宽格式。我可以只使用sql来实现这一点吗 用一个例子最容易解释。假设您有M个国家的(国家、键、值)信息,N个键(例如,键可以是收入、政治领导人、地区、大陆等) 在SQL中是否有方法使用宽格式的数据创建新表 select distinct key from table; //这会给我所有的钥匙 1) 然后如何使用这些关键元素创建表 2) 然后如何填写表中的值 我很确定我可以用任何脚本语言(我喜欢python)来实现这一点,但我想知道

我在mysql表中有长/高格式(如下所述)的数据,希望将其转换为宽格式。我可以只使用sql来实现这一点吗

用一个例子最容易解释。假设您有M个国家的(国家、键、值)信息,N个键(例如,键可以是收入、政治领导人、地区、大陆等)

在SQL中是否有方法使用宽格式的数据创建新表

select distinct key from table;
//这会给我所有的钥匙

1) 然后如何使用这些关键元素创建表

2) 然后如何填写表中的值

我很确定我可以用任何脚本语言(我喜欢python)来实现这一点,但我想知道在mysql中是否有一种简单的方法来实现这一点。许多统计软件包(如R和STATA)都内置了此命令,因为它经常被使用

======

更清楚地说,以下是一个简单情况下所需的输入输出:

输入:

country    attrName    attrValue     key  (these are column names)
US         President   Obama         2
US         Currency    Dollar        3
China      President   Hu            4
China      Currency    Yuan          5
输出

country    President    Currency    newPkey
US         Obama        Dollar      1
China      Hu           Yuan        2

如果您使用的是SQL Server,这将很容易使用。据我所知,这并不是在MySQL中实现的,所以如果您想这样做(我建议不要这样做),您可能必须动态生成SQL,这很麻烦。

我想我找到了解决方案,它使用视图和插入(如e4c5所建议的)

您必须自己获取属性名/键的列表,但MYSQL需要完成另一项繁重的工作

对于上面的简单测试用例,使用适当的列创建新的_表(别忘了还有一个自动递增主键)。然后

如果有更多属性名,则为每个属性名创建一个视图,然后相应地调整最后一条语句

INSERT INTO newtable(country, President, Currency, Capital, Population)
SELECT a.country, a.attrValue, b.attrValue, c.attrValue, d.attrValue
FROM  a
INNER JOIN b  ON a.country=b.country
INNER JOIN c  ON a.country=c.country
INNER JOIN d  ON a.country=d.country;
更多提示

  • 使用自然左连接,不必指定ON子句

答案是交叉表或数据透视表。从那里你可以选择。。。插入到。。。或从单个选择创建视图

比如:

SELECT country, 
       MAX( IF( key='President', value, NULL ) ) AS President,
       MAX( IF( key='Currency', value, NULL ) ) AS Currency,
       ...

FROM table 
GROUP BY country;

有关更多信息:

我的方式有效。你的方式好多了。我爱你还是谢谢你。选择你喜欢哪一个作为表达感激的方式。IF操作符是MySQL专有的。而是使用符合标准SQL的用例。这里有更多详细信息:@mluebke:您的链接已失效:(为什么每行都必须使用“max()”,而不是国家?因为您是按国家分组的,所以对于组来说,它始终是一个一致的值。
INSERT INTO newtable(country, President, Currency, Capital, Population)
SELECT a.country, a.attrValue, b.attrValue, c.attrValue, d.attrValue
FROM  a
INNER JOIN b  ON a.country=b.country
INNER JOIN c  ON a.country=c.country
INNER JOIN d  ON a.country=d.country;
SELECT country, 
       MAX( IF( key='President', value, NULL ) ) AS President,
       MAX( IF( key='Currency', value, NULL ) ) AS Currency,
       ...

FROM table 
GROUP BY country;