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

SQL Pivot将不同的值作为列名返回,sql,oracle,pivot,distinct,sql-like,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 -| 我正在尝试运行一个查询,该查询将根据字符串(如值中的5个左字符)返回的不同值将数据透视到多

我有一个具有此结构的表列:

|------ 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  -|
我正在尝试运行一个查询,该查询将根据字符串(如值中的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  -|

我使用的是oracle11gdb,所以我想我应该使用PIVOT命令,但我不知道如何通过添加DISTINCT和LIKE命令来设置它。任何帮助都将不胜感激。

作为选项一,您可以使用
行数()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                       
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                       
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                       

作为选项1,您可以使用
row\u 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                       
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                       
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                       

谢谢你的回复。我喜欢第二个选项,但是,列中的潜在值可能会改变。我刚刚阅读了关于pivot命令的Oracle文档,其中指出“这一行[for,in]是必需的,所以很遗憾,您必须事先知道可能的值。这一限制在本文后面描述的查询XML格式中得到了放松。”这似乎限制了我使用pivot命令的能力,XML也不是一个合理的选择。我会继续努力的。谢谢,谢谢你的回复。我喜欢第二个选项,但是,列中的潜在值可能会改变。我刚刚阅读了关于pivot命令的Oracle文档,其中指出“这一行[for,in]是必需的,所以很遗憾,您必须事先知道可能的值。这一限制在本文后面描述的查询XML格式中得到了放松。”这似乎限制了我使用pivot命令的能力,XML也不是一个合理的选择。我会继续努力的。谢谢