统一SQL 支持Oracle unpivot列转行

统一SQL介绍

https://www.light-pg.com/docs/LTSQL/current/index.html

源和目标

源数据库:Oracle

目标数据库:TDSQL-MySQL

操作目标

在Oracle中,可以使用unpivot将列转换成行,在TDSQL-MySQL中没有对应的功能,由此,通过统一SQL进行语句改写,在限定条件下支持unpivot的功能。

统一SQL转换

Oracle 的unpivot语法图

统一SQL支持语法图

上图矩形框部分

转换方案

使用TDSQL-MySQL的 UNION ALL 特性进行Oracle unpivot的替换

转换案例

-- 前置准备Oracle-SQL:
CREATE TABLE unisql_unpivot(id INT,name VARCHAR(64),chinese NUMBER,math INT,english INT);
INSERT INTO unisql_unpivot VALUES(1,'张三',70,90,95);
INSERT INTO unisql_unpivot VALUES(2,'李四',75,85,90);
INSERT INTO unisql_unpivot VALUES(3,'张三',90,90,90);
drop table unisql_unpivot;


-- 转换前Oracle SQL:
SELECT id,name,score,subject FROM unisql_unpivot UNPIVOT(score FOR subject IN(chinese, math, english)) WHERE id IN (1, 2, 3) ORDER BY id;
ID|NAME|SCORE|SUBJECT|
--+----+-----+-------+
1|张三  |   70|CHINESE|
1|张三  |   90|MATH   |
1|张三  |   95|ENGLISH|
2|李四  |   75|CHINESE|
2|李四  |   85|MATH   |
2|李四  |   90|ENGLISH|
3|张三  |   90|CHINESE|
3|张三  |   90|MATH   |
3|张三  |   90|ENGLISH|

-- 转换后TDSQL-MySQL
SELECT `id`,`name`,`chinese` AS `score`,'CHINESE' AS `subject` FROM `unisql_unpivot` WHERE `id` IN (1,2,3) UNION ALL SELECT `id`,`name`,`math` AS `score`,'MATH' AS `subject` FROM `unisql_unpivot` WHERE `id` IN (1,2,3) UNION ALL SELECT `id`,`name`,`english` AS `score`,'ENGLISH' AS `subject` FROM `unisql_unpivot` WHERE `id` IN (1,2,3) ORDER BY `id`
id|name|score|subject|
--+----+-----+-------+
1|张三  |   70|CHINESE|
1|张三  |   95|ENGLISH|
1|张三  |   90|MATH   |
2|李四  |   85|MATH   |
2|李四  |   75|CHINESE|
2|李四  |   90|ENGLISH|
3|张三  |   90|MATH   |
3|张三  |   90|CHINESE|
3|张三  |   90|ENGLISH|


 -- 转换前Oracle SQL:
SELECT id,name,score,subject FROM unisql_unpivot UNPIVOT(score FOR subject IN(chinese, math, english)) WHERE id IN (1, 2, 3) ORDER BY id,name,score,subject OFFSET 1 ROWS FETCH NEXT 2 ROWS ONLY;
ID|NAME|SCORE|SUBJECT|
--+----+-----+-------+
1|张三  |   90|MATH   |
1|张三  |   95|ENGLISH|

-- 转换后TDSQL-MySQL
    SELECT `id`,`name`,`chinese` AS `score`,'CHINESE' AS `subject` FROM `unisql_unpivot` WHERE `id` IN (1,2,3) UNION ALL SELECT `id`,`name`,`math` AS `score`,'MATH' AS `subject` FROM `unisql_unpivot` WHERE `id` IN (1,2,3) UNION ALL SELECT `id`,`name`,`english` AS `score`,'ENGLISH' AS `subject` FROM `unisql_unpivot` WHERE `id` IN (1,2,3) ORDER BY `id`,`name`,`score`,`subject` LIMIT 1,2
id|name|score|subject|
--+----+-----+-------+
1|张三  |   90|MATH   |
1|张三  |   95|ENGLISH|

使用限制

统一SQL当前对unpivot转换使用限制如下:
1. 只支持在单表查询语句中使用,参考如下:
  SELECT id,name,score AS sc,subject AS su FROM unisql_unpivot UNPIVOT(score FOR subject IN(chinese, math, english)) WHERE id IN (1, 2, 3,4,5) ORDER BY id;
2. 只支持单字段的unpivot,如上(score for subject)
3. 统一SQL会将unpivot in中的字段转换为大写,如上(chinese-->CHINESE, math-->MATH, english-->ENGLISH)
4. 不支持join,with, 子查询,group by, having,rownum
5. 不支持unpivot和unpivot for字段上使用函数,表达式
6. 不支持unpivot in语句中的字段使用AS
7. 分页查询存在offset时必须有fetch
8. 注意oracle和tdmysql字符集,排序规则等底层实现存在差异,排序字段需要保证是唯一序,否则可能导致两个库执行结果获取结果顺序不一致。

相关推荐

  1. 统一SQL-number/decimal/dec/numeric转换

    2024-04-24 18:14:01       13 阅读
  2. oracle 行转转行

    2024-04-24 18:14:01       7 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-04-24 18:14:01       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-04-24 18:14:01       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-04-24 18:14:01       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-04-24 18:14:01       20 阅读

热门阅读

  1. 【nginx安装内置的http_image_filter_module】

    2024-04-24 18:14:01       13 阅读
  2. 卡口车辆智能检索系统

    2024-04-24 18:14:01       11 阅读
  3. SQL仓库

    2024-04-24 18:14:01       10 阅读
  4. 嵌入式Linux—Framebuffer应用编程

    2024-04-24 18:14:01       16 阅读
  5. 研发管理规范

    2024-04-24 18:14:01       10 阅读
  6. 红帽系统Redhat忘记密码,重置root密码

    2024-04-24 18:14:01       12 阅读
  7. 神经网络与深度学习(四)

    2024-04-24 18:14:01       10 阅读
  8. ORA-25153:临时表空间为空

    2024-04-24 18:14:01       13 阅读
  9. 程序员的压力缓解之道:寻找工作与生活的平衡

    2024-04-24 18:14:01       13 阅读
  10. 孩子如何才能学好Scratch

    2024-04-24 18:14:01       13 阅读
  11. OpenResty实现限流的几种方式

    2024-04-24 18:14:01       12 阅读