2014-01-17 63 views
0

我有一个表:转换列成行

+--------------+-------+--------+----------+ 
| attribute_id | color | brand | category | 
+--------------+-------+--------+----------+ 
|   1 | red | honda | cars  | 
|   2 | blue | bmw | cars  | 
|   3 | pink | skonda | vans  | 
+--------------+-------+--------+----------+ 

我想将其转换为以下几点:

+--------------+---------+ 
| attribute_id | keyword | 
+--------------+---------+ 
|   1 | red  | 
|   2 | blue | 
|   3 | pink | 
|   1 | honda | 
|   2 | bmw  | 
|   3 | skonda | 
|   1 | cars | 
|   2 | cars | 
|   3 | vans | 
+--------------+---------+ 

我能想到的唯一方法是使用UNION就像这:

SELECT attribute_id, color from attributes 
UNION ALL 
SELECT attribute_id, brand from attributes 
UNION ALL 
SELECT attribute_id, category from attributes 

以上方式是有点麻烦,尤其是因为我的实际使用情况需要加入每个多个表选择。

有没有简单或更少复制/粘贴的方式写这个?

+1

更重要的是*你想用数据做什么? – Kermit

+0

@FreshPrinceOfSO - 我有一个设计很糟糕的表,有很多列,我想填充我新创建的关键字表。我将使用原始表格中的每个列作为关键字。 – Drahcir

+0

我只需从表格中正常选择*,然后使用您正在使用的任何语言进行处理。 –

回答

3

一个更高效的查询(至少对于较大的表)是:

SELECT attribute_id, 
     (case when n = 1 then color 
      when n = 2 then brand 
      when n = 3 then category 
     end) as keyword 
from attributes a cross join 
    (select 1 as n union all select 2 union all select 3) n; 

这之所以比union all查询更好是性能。 union all将扫描原始表格三次。这将扫描原始表格(然后通过n循环)。对于一张大桌子,这可能会在性能上产生重大差异。

+0

太棒了,谢谢你的技术。我从来没有发现过用于交叉连接。 – Drahcir