ORACLE 同表列转行

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ORACLE 同表列转行相关的知识,希望对你有一定的参考价值。

表test字段a1 a2 a3值 1 2 3 11 12 13我想查询结果把这六个值变成一列6条数据a123111213
由于实际表字段有30个union all 的话sql语句太长了,不知道有什么简便方法没

create table test (a1 number , a2 number , a3 number ) ;

insert into test values (1,2,3) ;
insert into test values (11,12,13) ;


dexter@REPO>select a from (
  2    SELECT *
  3      FROM test
  4           UNPIVOT(
  5           a
  6           for v
  7           IN(a1, a2, a3)
  8           ));

         A
----------
         1
         2
         3
        11
        12
        13

已选择6行。

用的是11g列转行函数,unpovit。 这些列的数据类型必须是一致的。试一下吧。

参考技术A 可以用oracle的分析函数listagg,但11g以后才有 参考技术B 列转行有如下方法。你试试这些
Sql代码
CREATE TABLE t_col_row(
ID INT,
c1 VARCHAR2(10),
c2 VARCHAR2(10),
c3 VARCHAR2(10));

INSERT INTO t_col_row VALUES (1, 'v11', 'v21', 'v31');
INSERT INTO t_col_row VALUES (2, 'v12', 'v22', NULL);
INSERT INTO t_col_row VALUES (3, 'v13', NULL, 'v33');
INSERT INTO t_col_row VALUES (4, NULL, 'v24', 'v34');
INSERT INTO t_col_row VALUES (5, 'v15', NULL, NULL);
INSERT INTO t_col_row VALUES (6, NULL, NULL, 'v35');
INSERT INTO t_col_row VALUES (7, NULL, NULL, NULL);
COMMIT;

SELECT * FROM t_col_row;
CREATE TABLE t_col_row(
ID INT,
c1 VARCHAR2(10),
c2 VARCHAR2(10),
c3 VARCHAR2(10));

INSERT INTO t_col_row VALUES(1, 'v11', 'v21', 'v31');
INSERT INTO t_col_row VALUES(2, 'v12', 'v22', NULL);
INSERT INTO t_col_row VALUES(3, 'v13', NULL, 'v33');
INSERT INTO t_col_row VALUES(4, NULL, 'v24', 'v34');
INSERT INTO t_col_row VALUES(5, 'v15', NULL, NULL);
INSERT INTO t_col_row VALUES(6, NULL, NULL, 'v35');
INSERT INTO t_col_row VALUES(7, NULL, NULL, NULL);
COMMIT;

SELECT * FROM t_col_row;
1)UNION ALL适用范围:8i,9i,10g及以后版本
Sql代码
SELECT id, 'c1' cn, c1 cv
FROM t_col_row
UNION ALL
SELECT id, 'c2' cn, c2 cv
FROM t_col_row
UNION ALL
SELECT id, 'c3' cn, c3 cv FROM t_col_row;
SELECT id, 'c1' cn, c1 cv
FROM t_col_row
UNION ALL
SELECT id, 'c2' cn, c2 cv
FROM t_col_row
UNION ALL
SELECT id, 'c3' cn, c3 cv FROMt_col_row;
若空行不需要转换,只需加一个where条件,
Sql代码
WHERE COLUMN IS NOT NULL
WHERE COLUMN IS NOT NULL
即可。2)MODEL适用范围:10g及以后
Sql代码
SELECT id, cn, cv FROM t_col_row
MODEL
RETURN UPDATED ROWS
PARTITION BY (ID)
DIMENSION BY (0 AS n)
MEASURES ('xx' AS cn,'yyy' AS cv,c1,c2,c3)
RULES UPSERT ALL
(
cn[1] = 'c1',
cn[2] = 'c2',
cn[3] = 'c3',
cv[1] = c1[0],
cv[2] = c2[0],
cv[3] = c3[0]
)
ORDER BY ID,cn;
SELECT id, cn, cv FROMt_col_row
MODEL
RETURN UPDATED ROWS
PARTITION BY (ID)
DIMENSION BY (0 AS n)
MEASURES ('xx' AS cn,'yyy' AScv,c1,c2,c3)
RULES UPSERT ALL
(
cn[1] = 'c1',
cn[2] = 'c2',
cn[3] = 'c3',
cv[1] = c1[0],
cv[2] = c2[0],
cv[3] = c3[0]
)
ORDER BY ID,cn;
3)collection适用范围:8i,9i,10g及以后版本要创建一个对象和一个集合:
Sql代码
CREATE TYPE cv_pair AS OBJECT(cn VARCHAR2(10),cv VARCHAR2(10));

CREATE TYPE cv_varr AS VARRAY(8) OF cv_pair;

SELECT id, t.cn AS cn, t.cv AS cv
FROM t_col_row,
TABLE(cv_varr(cv_pair('c1', t_col_row.c1),
cv_pair('c2', t_col_row.c2),
cv_pair('c3', t_col_row.c3))) t
ORDER BY 1, 2;
参考技术C 用循环试试

leetcode上升的温度--oracle同表比较

给定一个 Weather 表,编写一个 SQL 查询,来查找与之前(昨天的)日期相比温度更高的所有日期的 Id。

+---------+------------------+------------------+
| Id(INT) | RecordDate(DATE) | Temperature(INT) |
+---------+------------------+------------------+
|       1 |       2015-01-01 |               10 |
|       2 |       2015-01-02 |               25 |
|       3 |       2015-01-03 |               20 |
|       4 |       2015-01-04 |               30 |
+---------+------------------+------------------+

例如,根据上述给定的 Weather 表格,返回如下 Id:

+----+
| Id |
+----+
|  2 |
|  4 |
+----+

方法:

oracle 日期类型的直接使用+1来表示日期差。

因此,我们可以通过将 weather 与自身比较

/* Write your PL/SQL query statement below */
select a.Id from Weather a,Weather b where a.RecordDate=b.RecordDate+1 and a.Temperature>b.Temperature

 



以上是关于ORACLE 同表列转行的主要内容,如果未能解决你的问题,请参考以下文章

oracle列转行函数

Oracle列转行,行转列

Hive 行转列 & 列转行

oracle 列转行

oracle 多列 列转行

oracle 列转行的问题。图1是数据库查询的结果 图二是我想要的结果的格式,谢谢了。