Mysql,重塑从长/高到宽的数据

cho*_*man 23 mysql sql statistics reshape

我有一个长/高格式的mysql表中的数据(如下所述),并希望将其转换为宽格式.我可以只使用sql吗?

最简单的解释一个例子.假设您有关于M个国家(国家,关键,价值)的信息,N个密钥(例如,密钥可以是收入,政治领导者,地区,大陆等)

Long format has 3 columns: country, key, value
  - M*N rows.
  e.g. 
  'USA', 'President', 'Obama'
   ...
  'USA', 'Currency', 'Dollar'

Wide format has N=16 columns: county, key1, ..., keyN
  - M rows
example: 
   country, President, ... , Currency
   'USA', 'Obama', ... , 'Dollar'
Run Code Online (Sandbox Code Playgroud)

SQL中是否有一种方法可以创建一个包含宽格式数据的新表?

select distinct key from table;
Run Code Online (Sandbox Code Playgroud)

//这会给我所有的钥匙.

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
Run Code Online (Sandbox Code Playgroud)

产量

country    President    Currency    newPkey
US         Obama        Dollar      1
China      Hu           Yuan        2
Run Code Online (Sandbox Code Playgroud)

mlu*_*bke 20

交叉表或数据透视表就是答案.从那里你可以SELECT FROM ... INSERT INTO ...或者从单个SELECT创建一个VIEW.

就像是:

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

FROM table 
GROUP BY country;
Run Code Online (Sandbox Code Playgroud)

有关更多信息:http://dev.mysql.com/tech-resources/articles/wizard/index.html

  • 我的方式有效.你的方式好多了.我爱你或谢谢.选择您喜欢哪一种作为表达欣赏的方式. (5认同)
  • IF运算符是MySQL专有的。请改用CASE以便与标准SQL兼容。此处有更多详细信息:[SQLite是长格式还是宽格式?](http://www.stackoverflow.com/questions/2444708/sqlite-long-to-wide-formats) (2认同)

Mar*_*ers 5

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


cho*_*man 5

我想我找到了解决方案,它使用VIEWS和INSERT INTO(如e4c5所示).

你必须自己获得你的AttrNames/Keys列表,但是MYSQL做了另一个繁重的工作.

对于上面的简单测试用例,使用适当的列创建new_table(不要忘记也有自动增量主键).然后

CREATE VIEW a
AS SELECT country, attrValue
WHERE attrName="President";

CREATE VIEW b
AS SELECT country, attrValue
WHERE attrName="Currency";


INSERT INTO newtable(country, President, Currency)
SELECT a.country, a.attrValue, b.attrValue
FROM  a
INNER JOIN b  ON a.country=b.country;
Run Code Online (Sandbox Code Playgroud)

如果您有更多的attrNames,则为每个创建一个视图,然后相应地调整最后一个语句.

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;
Run Code Online (Sandbox Code Playgroud)

更多提示

  • 使用NATURAL LEFT JOIN,您不必指定ON子句