SQL Pivot将不同的值作为列名返回

时间:2013-11-01 15:05:08

标签: sql oracle pivot distinct sql-like

我有一个具有这种结构的表格列:

|------ ID ------|
|-  1.20.10.00  -|
|-  1.20.10.10  -|
|-  1.20.10.20  -|
|-  1.20.20.00  -|
|-  1.20.20.10  -|
|-  1.40.10.00  -|
|-  1.40.20.00  -|
|-  1.60.10.00  -|
|-  1.60.10.00  -|

我正在尝试运行一个查询,该查询将根据字符串返回的Distinct值将数据转换为多个列。与值中的5个左字符匹配,列名与like语句中使用的5个字符匹配。让我举一个我想要的例子:

|----- 1.20. ----||----- 1.40. ----||----- 1.60. ----|
|-  1.20.10.00  -||-  1.40.10.00  -||-  1.60.10.00  -|
|-  1.20.10.10  -||-  1.40.20.00  -||-  1.60.10.00  -|
|-  1.20.10.20  -|
|-  1.20.20.00  -|
|-  1.20.20.10  -|

我在Oracle 11g数据库上,所以我认为我应该使用PIVOT命令,但我无法弄清楚如何通过添加DISTINCT和LIKE命令来设置它。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

作为第一个选项,您可以使用row_number() over()分析函数,max()聚合函数和case表达式的组合:

select max(case when substr(col, 1, 4) = '1.20' then col end) as "1.20"
     , max(case when substr(col, 1, 4) = '1.40' then col end) as "1.40"
     , max(case when substr(col, 1, 4) = '1.60' then col end) as "1.60"
 from (select col
            , row_number() over(partition by substr(col, 1, 4) 
                                    order by substr(col, 1, 4)) as rn
        from t1)
group by rn

结果:

1.20       1.40       1.60     
---------- ---------- ----------
1.20.10.00 1.40.10.00 1.60.10.00 
1.20.10.10 1.40.20.00 1.60.10.00 
1.20.20.00                       
1.20.20.10                       
1.20.10.20                       

注意:想到的列别名不是很好的选择。

作为另一种选择,您可以使用Oracle 11g版本中引入的pivot运算符:

select "1.20"
     , "1.40"
     , "1.60"
       from (select col
                  , substr(col, 1, 4) as common_part
                  , row_number() over(partition by substr(col, 1, 4) 
                                          order by substr(col, 1, 4)) as rn
              from t1)
pivot(
  max(col) for common_part in ( '1.20' as "1.20"
                              , '1.40' as "1.40"
                              , '1.60' as "1.60")
)

结果:

1.20       1.40       1.60     
---------- ---------- ----------
1.20.10.00 1.40.10.00 1.60.10.00 
1.20.10.10 1.40.20.00 1.60.10.00 
1.20.20.00                       
1.20.20.10                       
1.20.10.20