【问题标题】:SQL Pivot to Return Distinct Values as Column NameSQL Pivot 将不同的值作为列名返回
【发布时间】:2013-11-01 15:05:08
【问题描述】:

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

|------ 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  -|

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

【问题讨论】:

    标签: sql oracle pivot distinct sql-like


    【解决方案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                       
    

    【讨论】:

    • 感谢您的回复。我喜欢第二个选项,但是,列中的潜在值可能会改变。我刚刚阅读了枢轴命令link 的Oracle 文档,其中指出“这条线[for,in] 是必要的,所以不幸的是你必须事先知道可能的值。这个限制在查询的XML 格式中放宽了,将在本文后面介绍。”这似乎限制了我使用 pivot 命令的能力,并且 XML 不是一个合理的选择。我会继续努力。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多