Sql oracle中是否有任何语句可以将行值转换为同一行但不同的列?

Sql oracle中是否有任何语句可以将行值转换为同一行但不同的列?,sql,oracle,plsql,oracle11g,pivot,Sql,Oracle,Plsql,Oracle11g,Pivot,我希望有人能给我一个问题的答案 我得到了一个表(即表1),它看起来像这样,我希望它像我在图片中显示的那样: 表1 "number" "date" time ------- ---------- ----- 001 19.09.2020 12:30 001 19.09.2020 14:31 002 19.09.2020 11:20 001 19.09.2020

我希望有人能给我一个问题的答案

我得到了一个表(即
表1
),它看起来像这样,我希望它像我在图片中显示的那样:

表1

"number"  "date"        time
 -------  ----------    -----
 001      19.09.2020    12:30
 001      19.09.2020    14:31
 002      19.09.2020    11:20
 001      19.09.2020    17:20
 002      19.09.2020    14:00
 001      19.09.2020    19:01
预期结果(对于“数字”=“001”):


有一些静态数据透视方法,如使用
PIVOT
子句和
条件聚合
,其中所有生成的数据透视列都应显式指定,而有直接动态方法,通过使用仅SQL

我认为在存储函数中使用
SYS\u REFCURSOR
非常适合您的情况:

CREATE OR REPLACE FUNCTION 
   Get_Table1_RS(
                  i_number        table1."number"%TYPE
                 ) RETURN SYS_REFCURSOR IS
  v_recordset SYS_REFCURSOR;
  v_sql       VARCHAR2(32767);
  v_str       VARCHAR2(32767);
BEGIN
  SELECT LISTAGG( ''''||time||''' AS "'||LOWER(c.column_name)||t.rn||'"' , ',' ) 
                 WITHIN GROUP ( ORDER BY time )
    INTO v_str
    FROM ( SELECT t1.*, ROW_NUMBER() OVER (ORDER BY time) AS rn 
             FROM table1 t1
            WHERE "number" = '001' ) t 
    LEFT JOIN user_tab_cols c
      ON c.table_name = 'TABLE1' 
     AND c.column_name like 'TIME%';  

  v_sql :=
  'SELECT *
     FROM table1
    PIVOT
    (
     MAX(time) FOR time IN ( '|| v_str ||' )
    )
    WHERE "number" = :nr';

  OPEN v_recordset FOR v_sql USING i_number;
  RETURN v_recordset;
END;
/
为了获得动态生成的结果集(例如,动态轴

然后运行以下代码:

VAR rc REFCURSOR
EXEC :rc := Get_Table1_RS('001');
PRINT rc
从SQL Developer的命令行,以查看结果集

如果仍希望仅使用SQL查询,则更喜欢使用:

枢轴子句的情况:

SELECT *
  FROM table1
 PIVOT 
   (
    MAX(time) FOR time IN ( '12:30' AS "time1",'14:31' AS "time2",
                            '17:20' AS "time3",'19:01' AS "time4" )
   )
 WHERE "number" = '001';


   
  number date         time1 time2 time3 time4
  ------ -----------  ----- ----- ----- -----
  001    19.09.2020   12:30 14:31 17:20 19:01
  
条件聚合的情况

SELECT "number", "date", 
       MAX(CASE WHEN rn = 1 THEN time END) AS "time1",
       MAX(CASE WHEN rn = 2 THEN time END) AS "time2",
       MAX(CASE WHEN rn = 3 THEN time END) AS "time3",
       MAX(CASE WHEN rn = 4 THEN time END) AS "time4"  
  FROM ( SELECT ROW_NUMBER() OVER (ORDER BY time) AS rn,
                t1.*
           FROM table1 t1
          WHERE "number" = '001' ) t  
 GROUP BY "number", "date"    

  number date         time1 time2 time3 time4
  ------ -----------  ----- ----- ----- -----
  001    19.09.2020   12:30 14:31 17:20 19:01

您希望它作为列还是所有时间列的逗号分隔值也适合您的要求?如果我们使用
pivot
,您对每个数字的硬编码值满意吗?每个数字
001
的行是未知的吗?我想提一点,我认为我们也可以在pivoting子句中使用相同的行号,而不是time列。(Listag:可以获得4000个字符的限制)是的,也可以@Sujitmohanty30,但星号已经足够了:)
SELECT "number", "date", 
       MAX(CASE WHEN rn = 1 THEN time END) AS "time1",
       MAX(CASE WHEN rn = 2 THEN time END) AS "time2",
       MAX(CASE WHEN rn = 3 THEN time END) AS "time3",
       MAX(CASE WHEN rn = 4 THEN time END) AS "time4"  
  FROM ( SELECT ROW_NUMBER() OVER (ORDER BY time) AS rn,
                t1.*
           FROM table1 t1
          WHERE "number" = '001' ) t  
 GROUP BY "number", "date"    

  number date         time1 time2 time3 time4
  ------ -----------  ----- ----- ----- -----
  001    19.09.2020   12:30 14:31 17:20 19:01