重温SQL行转列,性能又双叒提升了

简介: 重温SQL行转列,性能又双叒提升了

行列转换包括以下六种情况:

  1. 列转行
  2. 行转列
  3. 多列转换成字符串
  4. 多行转换成字符串
  5. 字符串转换成多列
  6. 字符串转换成多行


🍁 一、列转行



简单的说就是将原表中的列名作为转换后的表的内容,这就是列转行


🍃 1.1 UNION ALL


create table TEST_JEM
(
NAME VARCHAR2(255),
JANUARY NUMBER(18),
FEBRUARY NUMBER(18),
MARCH NUMBER(18),
APRIL NUMBER(18),
MAY NUMBER(18)
);
insert into TEST_JEM(NAME, JANUARY, FEBRUARY, MARCH, APRIL, MAY)
values ('长寿', 58, 12, 26, 18, 269);
insert into TEST_JEM(NAME, JANUARY, FEBRUARY, MARCH, APRIL, MAY)
values ('璧山', 33, 18, 17, 16, 206);
insert into TEST_JEM(NAME, JANUARY, FEBRUARY, MARCH, APRIL, MAY)
values ('杨家坪', 72, 73, 79, 386, 327);
insert into TEST_JEM(NAME, JANUARY, FEBRUARY, MARCH, APRIL, MAY)
values ('巫溪', 34, 9, 7, 21, 33);
insert into TEST_JEM(NAME, JANUARY, FEBRUARY, MARCH, APRIL, MAY)
values ('丰都', 62, 46, 39, 36, 91);
insert into TEST_JEM(NAME, JANUARY, FEBRUARY, MARCH, APRIL, MAY)
values ('武隆', 136, 86, 44, 52, 142);
commit;


SELECT * FROM TEST_JEM;

eea9498279b84ae1a8b6fed0636bade6.png



⛳️ 行转列如下


SELECT *
  FROM (SELECT t.name, 'january' MONTH, t.january v_num
          FROM TEST_JEM t
        UNION ALL
        SELECT t.name, 'february' MONTH, t.february v_num
          FROM TEST_JEM t
        UNION ALL
        SELECT t.name, 'march' MONTH, t.march v_num
          FROM TEST_JEM t
        UNION ALL
        SELECT t.name, 'april' MONTH, t.april v_num
          FROM TEST_JEM t
        UNION ALL
        SELECT t.name, 'may' MONTH, t.may v_num FROM TEST_JEM t)
 ORDER BY NAME;


a07988e5e25a4715af983786dcd0ac1a.png

🍃 1.2 insert all into … select

60f0a5b0493442b693485e7a4fa332a4.png 2b26900d042b4ead9205f14dc5400403.png
首先创建需要的表, test_row
create table test_row
(
NAME VARCHAR2(255),
MONTH VARCHAR2(8),
V_NUM NUMBER(18)
);
SQL> desc test_row

cfaeca12618541288b861e214c52ed40.png


然后执行下边的 sql 语句:
注意:查询test_jem 的表进行插入
insert all
into test_row(NAME,month,v_num) values(name, 'may', may)
into test_row(NAME,month,v_num) values(name, 'april', april)
into test_row(NAME,month,v_num) values(name, 'february', february)
into test_row(NAME,month,v_num) values(name, 'march', march)
into test_row(NAME,month,v_num) values(name, 'january', january)
select t.name,t.january,t.february,t.march,t.april,t.may from test_jem t;
commit;

select * from test_row;

5e6e7c5c8b9642d894c665c66dd0b824.png


🍃 1.3 MODEL


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;


84ea29d98c764707bf77047c73ec9e58.png


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;

0a1dd4cd8be74dbe9260e377aa21a9d5.png


🍁 二、行转列



行转列就是将行数据内容作为列名

35304c12cd8046ed99f55f67c85bf9d6.png

CREATE TABLE t_row_col AS
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 * FROM t_row_col ORDER BY 1,2;


88ce513f7f75425ab0c2f9a3864955fa.png


🍃 2.1 max+decode


SELECT id,
       MAX(decode(cn, 'c1', cv, NULL)) AS c1,
       MAX(decode(cn, 'c2', cv, NULL)) AS c2,
       MAX(decode(cn, 'c3', cv, NULL)) AS c3
  FROM t_row_col
 GROUP BY id
 ORDER BY 1;

cb6b743bb4764d0eb4d3cddc366b134b.png


SELECT t.name,
MAX(decode(t.month, 'may', t.v_num)) AS may,
MAX(decode(t.month, 'april', t.v_num)) AS april,
MAX(decode(t.month, 'february', t.v_num)) AS february,
MAX(decode(t.month, 'march', t.v_num)) AS march,
MAX(decode(t.month, 'january', t.v_num)) AS january
FROM test_row t
GROUP BY t.name;

b2021b0d506345c99e9d80e73cce4713.png


如果要实现对各个不同的区间进行统计,则:

SELECT * FROM test_row t ORDER BY t.name, t.month;


6f9b4edd4bd244d2b91f9e629df60860.png


SELECT t.name,
       CASE
         WHEN t.v_num < 100 THEN
          '0-100'
         WHEN t.v_num >= 100 AND t.v_num < 200 THEN
          '100-200'
         WHEN t.v_num >= 200 AND t.v_num < 300 THEN
          '200-300'
         WHEN t.v_num >= 300 AND t.v_num < 400 THEN
          '300-400'
       END AS grade,
       COUNT(t.v_num) count_num
  FROM test_row t
 GROUP BY t.name,
          CASE
            WHEN t.v_num < 100 THEN
             '0-100'
            WHEN t.v_num >= 100 AND t.v_num < 200 THEN
             '100-200'
            WHEN t.v_num >= 200 AND t.v_num < 300 THEN
             '200-300'
            WHEN t.v_num >= 300 AND t.v_num < 400 THEN
             '300-400'
          END;

fba3c833001c44528e2681a194cb59de.png


🍁 三、多列转换成字符串



CREATE TABLE t_col_str AS
SELECT * FROM t_col_row;
这个比较简单,用|| 或 concat 函数可以实现:
SELECT concat('a','b') FROM dual;
SELECT ID,
c1 || ',' || c2 || ',' || c3 AS c123
FROM t_col_str;

6a9561ac70574f2f839b18b0dede172e.png



🍁 四、多行转换成字符串



CREATE TABLE t_row_str(
ID INT,
col VARCHAR2(10)
);
INSERT INTO t_row_str VALUES(1,'a');
INSERT INTO t_row_str VALUES(1,'b');
INSERT INTO t_row_str VALUES(1,'c');
INSERT INTO t_row_str VALUES(2,'a');
INSERT INTO t_row_str VALUES(2,'d');
INSERT INTO t_row_str VALUES(2,'e');
INSERT INTO t_row_str VALUES(3,'c');
COMMIT;
SELECT * FROM t_row_str;


8f6897fd7ab44f878fb2d32cd59fa992.png

4.1 ROW_NUMBER + LEAD


SELECT id, str
  FROM (SELECT id,
               row_number() over(PARTITION BY id ORDER BY col) AS rn,
               col || lead(',' || col, 1) over(PARTITION BY id ORDER BY col) ||
                lead(',' || col, 2) over(PARTITION BY id ORDER BY col) ||
                 lead(',' || col, 3) over(PARTITION BY id ORDER BY col) AS str
          FROM t_row_str)
 WHERE rn = 1
 ORDER BY 1;

2062f5e9c9124fd29fc02312060901f6.png


目录
相关文章
|
3月前
|
SQL 存储 关系型数据库
如何巧用索引优化SQL语句性能?
本文从索引角度探讨了如何优化MySQL中的SQL语句性能。首先介绍了如何通过查看执行时间和执行计划定位慢SQL,并详细解析了EXPLAIN命令的各个字段含义。接着讲解了索引优化的关键点,包括聚簇索引、索引覆盖、联合索引及最左前缀原则等。最后,通过具体示例展示了索引如何提升查询速度,并提供了三层B+树的存储容量计算方法。通过这些技巧,可以帮助开发者有效提升数据库查询效率。
218 2
|
2月前
|
SQL 数据库 UED
SQL性能提升秘籍:5步优化法与10个实战案例
在数据库管理和应用开发中,SQL查询的性能优化至关重要。高效的SQL查询不仅可以提高应用的响应速度,还能降低服务器负载,提升用户体验。本文将分享SQL优化的五大步骤和十个实战案例,帮助构建高效、稳定的数据库应用。
72 3
|
2月前
|
SQL IDE 数据库连接
IntelliJ IDEA处理大文件SQL:性能优势解析
在数据库开发和管理工作中,执行大型SQL文件是一个常见的任务。传统的数据库管理工具如Navicat在处理大型SQL文件时可能会遇到性能瓶颈。而IntelliJ IDEA,作为一个强大的集成开发环境,提供了一些高级功能,使其在执行大文件SQL时表现出色。本文将探讨IntelliJ IDEA在处理大文件SQL时的性能优势,并与Navicat进行比较。
35 4
|
2月前
|
SQL 存储 缓存
如何优化SQL查询性能?
【10月更文挑战第28天】如何优化SQL查询性能?
166 10
|
2月前
|
SQL 关系型数据库 MySQL
惊呆:where 1=1 可能严重影响性能,差了10多倍,快去排查你的 sql
老架构师尼恩在读者交流群中分享了关于MySQL中“where 1=1”条件的性能影响及其解决方案。该条件在动态SQL中常用,但可能在无真实条件时导致全表扫描,严重影响性能。尼恩建议通过其他条件或SQL子句命中索引,或使用MyBatis的`&lt;where&gt;`标签来避免性能问题。他还提供了详细的执行计划分析和优化建议,帮助大家在面试中展示深厚的技术功底,赢得面试官的青睐。更多内容可参考《尼恩Java面试宝典PDF》。
|
2月前
|
SQL 缓存 监控
SQL性能提升指南:五大优化策略与十个实战案例
在数据库性能优化的世界里,SQL优化是提升查询效率的关键。一个高效的SQL查询可以显著减少数据库的负载,提高应用响应速度,甚至影响整个系统的稳定性和扩展性。本文将介绍SQL优化的五大步骤,并结合十个实战案例,为你提供一份详尽的性能提升指南。
55 0
|
3月前
|
SQL 监控 数据库
慢SQL对数据库写入性能的影响及优化技巧
在数据库管理系统中,慢SQL(即执行缓慢的SQL语句)不仅会影响查询性能,还可能对数据库的写入性能产生显著的不利影响
|
3月前
|
SQL 关系型数据库 PostgreSQL
遇到SQL 子查询性能很差?其实可以这样优化
遇到SQL 子查询性能很差?其实可以这样优化
156 2
|
3月前
|
SQL Oracle 关系型数据库
Oracle SQL:了解执行计划和性能调优
Oracle SQL:了解执行计划和性能调优
82 1
|
3月前
|
SQL 存储 数据库
慢SQL对数据库写入性能的影响及优化技巧
在数据库管理系统中,慢SQL(即执行缓慢的SQL语句)不仅会影响查询性能,还可能对数据库的写入性能产生显著的不利影响