sql查询双

时间:2010-09-29 04:50:34

标签: sql oracle pivot

此:

    select * 
      from dual  
connect by level <= i  

...将返回结果

1
2
3
...
i

可以修改查询以获得结果行吗?即

1 2 3 .....i

2 个答案:

答案 0 :(得分:4)

您所追求的功能称为“枢轴” - 它将行数据转换为柱状数据。相反的是“unpivot”。有PIVOT / UNPIVOT语法,但在Oracle 11g之前它不可用。

在Oracle 9i +上,使用CASE statements之前,您需要使用DECODE来构造逻辑,以便值以列的形式出现。下面是一个示例,用于解决Oracle 9i +上LEVEL限制为5的情况:

    SELECT MAX(CASE WHEN LEVEL = 1 THEN LEVEL END) AS one,
           MAX(CASE WHEN LEVEL = 2 THEN LEVEL END) AS two,
           MAX(CASE WHEN LEVEL = 3 THEN LEVEL END) AS three,
           MAX(CASE WHEN LEVEL = 4 THEN LEVEL END) AS four,
           MAX(CASE WHEN LEVEL = 5 THEN LEVEL END) AS five
      FROM DUAL
CONNECT BY LEVEL <= 5

聚合函数MAX是将结果集“展平”为单行/记录所必需的。

如果你到目前为止,你正在考虑“但我不想为每一列指定 - 我希望它基于 i ...”是动态的。有两个问题:

  1. 列数有限制 - 请参阅ORA-01792 maximum number of columns in a table or view is 1000。这适用于8i&amp; 9i,反正。坦率地说,如果可能有更好的方法,那么需要生成那么多列会引发关于您尝试对结果集做什么的严重问题......
  2. Dynamic requirements means using dynamic SQL

答案 1 :(得分:1)

试试这个:

select trim(both ',' from sys_connect_by_path(level, ',')) as string
  from dual
 where level = 100
connect by level <= 100

更新:测试输出:

SQL> 
SQL>  select trim(both ',' from sys_connect_by_path(level, ',')) as string
  2     from dual
  3    where level = 20
  4   connect by level <= 20
  5  /

STRING
--------------------------------------------------------------------------------
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20

另一次更新:猜猜我发布之前没有充分阅读所有评论,抱歉。 :)如果你需要选择每个数字作为一个单独的列,那么是的,请参阅OMG Ponies的答案 - 它是枢轴或动态SQL。 :)