ORACLE 同表列转行
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ORACLE 同表列转行相关的知识,希望对你有一定的参考价值。
表test字段a1 a2 a3值 1 2 3 11 12 13我想查询结果把这六个值变成一列6条数据a123111213
由于实际表字段有30个union all 的话sql语句太长了,不知道有什么简便方法没
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 同表列转行的主要内容,如果未能解决你的问题,请参考以下文章