Oracle JSON_ARRAYAGG()函数的排序失效问题

news2024/12/23 6:07:46

引入:

在实际操作中,俺写了这样一个Funtcion:

    FUNCTION fun_get_xxx(v_param_one VARCHAR2) RETURN CLOB AS
        v_OUTPUT CLOB;
    BEGIN
        WITH temp_table AS (
        	SELECT * FROM (
				( SELECT one.action_id,
                         two.log_time
				  FROM table_one one
                  LEFT JOIN table_two two on two.action_id = one.action_id
                  WHERE one.action_id = v_param_one
                )
               	UNION
                ( SELECT one.action_id,
                         two.log_time
                  FROM table_three three
                  LEFT JOIN table_four four on four.action_id = three.action_id
                  WHERE three.action_id = v_param_one)
                )
        	)
        	ORDER BY log_time DESC
        	
        SELECT JSON_OBJECT(
                       'numOfRecords' VALUE count(temp_table .action_id),
                       'records' VALUE (
                       		JSON_ARRAYAGG(
                                   JSON_OBJECT(
                                           'actionId'  VALUE temp_table.action_id,
                                           'logTime' VALUE temp_table.log_time
                                   )
                       		)
                       ) format json returning clob
               )
        INTO v_OUTPUT
        from temp_table;
        RETURN v_OUTPUT;
    END fun_get_xxx;

WITH子句中,对数据进行了关于log_time列的ORDER BY 排序,

因为中间用了UNION,因此是把ORDER BY子句放到了外层的SELECT语句中的,因此能保证排序不受UNION影响,

但是根据返回的结果显示,关于log_time的排序是失败的,但它并不是没有排序,而是关于action_id排序,

试过把ORDER BY子句放到UNION语句中,也不行,

然后怀疑上了那两个JSON封装函数头上,最终在JSON_ARRAYAGG()函数上找到了解决办法。

最终修改成如下:

-- 省略...
        SELECT JSON_OBJECT(
                       'numOfRecords' VALUE count(temp_table .action_id),
                       'records' VALUE (
                       		JSON_ARRAYAGG(
                                   JSON_OBJECT(
                                           'actionId'  VALUE temp_table.action_id,
                                           'logTime' VALUE temp_table.log_time
                                   )
                       		)  ORDER BY log_time DESC -- 把排序放到了这里
                       ) format json returning clob
               )
-- 省略...

原因:

先看官方文档关于JSON_ARRAYAGG()函数的结构说明:
在这里插入图片描述
可以看到JSON_ARRAYAGG()函数的结构是可以包含ORDER BY子句的。

The JSON_ARRAYAGG function is used to aggregate data from multiple rows into a single JSON array. When using this function, the data will be ordered by the unique key because the function automatically orders the data based on the order of the rows in the result set.
大概意思:
JSON_ARRAYAGG函数用于将多行数据聚合成一个JSON数组。在使用此函数时,数据将按照唯一键进行排序,因为该函数会根据结果集中行的顺序自动对数据进行排序。

所以当JSON_ARRAYAGG()函数里面没有指定ORDER BY子句的时候,他就不能保证顺序问题,不清楚在这个封装过程它有没有对数据进行重新排序。

按说在WITH中的temp_table应该是已经排好序了的,因为俺单独把那一组语句拉出来跑,得到的结果排序没问题,非常可能在进行json封装的过程中,因为没有指定ORDER BY子句,不知道按照啥条件又排序了,导致了上一次排序失效。

问了问 chatGPT:

it is possible that the ordering is lost when aggregating the results into a JSON array using the json_arrayagg function

当使用json_arrayagg函数将结果聚合到JSON数组中时,可能会丢失原来的排序。

The reason why aggregating the results into a JSON array using the json_arrayagg function can lose the ordering is because the function does not guarantee any specific order of the elements in the resulting array. The order of the elements may be affected by various factors such as the order in which they are retrieved from the database, how they are processed by the function, and other internal implementation details.

使用json_arrayagg函数将结果聚合到JSON数组中可能会失去排序的原因是因为该函数不能保证结果数组中元素的任何特定顺序。元素的顺序可能受到各种因素的影响,比如从数据库中检索元素的顺序、函数处理元素的方式以及其他内部实现细节。

所以在用到JSON_ARRAYAGG()函数且需要排序时,把排序写在JSON_ARRAYAGG()函数内才能达到想要的排序效果。
大大的乌龙~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/674834.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【深度学习】6-4 卷积神经网络 - CNN的实现

CNN的实现 网络的构成是“Convolution - ReLU - Pooling -Affine - ReLU - Affine - Softmax”,我们将它实现为名为 SimpleConvNet的类。 首先来看一下 SimpleConvNet的初始化(init),取下面这些参数。 input_dim——输入数据的维…

七彩虹CN600+Meetiger N10C测评

七彩虹CN600这款M.2固态硬盘的参数就不多说了 本期采用为512版本 迷虎品牌,英文名Meetiger,Meetiger/迷虎品牌成立于2012年,品牌迷虎产品主要有硬盘底座,保护盒,硬盘座,移动硬盘盒子,硬盘盒子,... 以下就是本期的硬盘盒 当这两样东西在一起…

C++(10):泛型算法

泛型算法:可用于不同类型的容器和不同类型的元素的通用算法。 概述 大多数算法都定义在头文件algorithm 中。标准库在头文件 numeric 中定义了一组数值泛型算法。 一般情况下,泛型算法不直接操作容器,而是遍历由两个迭代器指定的一个元素范…

【Spring Boot学习】日志文件,Spring Boot也会写日记了,这些事你知道嘛 ? ? ?

前言: 大家好,我是良辰丫,在上一篇文章中我们已经学习了Spring Boot的配置,接下来我们要学习一些日志相关的东西,什么是日志呢?我们慢慢往下看.💌💌💌 🧑个人主页:良辰针不戳 📖所属专栏:javaE…

7.4_2B树的插入删除

我们先设置根节点 我们再往里面插入关键字 比如说:80 中间位置为49:(5/2)向上取整为3 新元素一定要插入到最底层”终端结点“,用”查找”来确定插入位置。 失败节点(叶子节点不属于同一层) 讲…

Vue-全局事件总线(GlobalEventBus)

全局事件总线(GlobalEventBus) 全局事件总线是vue中特别厉害的一种组件中通信的方式,它可以实现任意组件中通信,随便拿出来两个组件就能互通数据,就像对讲机一样,它在开发中用的也是特别的多 1 编写案例 首先准备两个组件&…

Python列表 (超详细举例加讲解)

得之我幸,失之我命 文章目录 1.列表的值 2.列表的定义 3.下标 4.列表长度 5.列表的加法和乘法 6.列表切片 7.操作方法(一些基础的函数) (1)append——向列表末尾添加元素 (2)insert——…

VUE3实现页面缓存,tab切换时不刷新

如上图所示,为了实现页面缓存,防止每次页面切换时重新刷新数据,前前后后尝试了多种写法,如上图被注释的那段写法,与没注释掉的写法,在router-view上主要是第一种写法有设置key属性,第二种没有&a…

常见面试题之框架篇

1.Spring框架中的单例bean是线程安全的吗? 不是线程安全的,是这样的。 当多用户同时请求一个服务时,容器会给每一个请求分配一个线程,这是多个线程会并发执行该请求对应的业务逻辑(成员方法),…

模拟电路系列分享-负反馈电路稳定性分析

目录 概要 整体架构流程 技术名词解释 1.负反馈放大电路产生自激震荡的条件 2.从实际运放的幅频,相频特性看自激振荡的可能性 小结 概要 在卡拉0K歌厅中,我们会见到这样一种现象:当麦克风位置不合适或者音量过大时, 喇叭中会出现一种非常难听的啸叫,捂住麦克风、赶紧…

【无需显卡】AI绘画入门教程

前言 Hello,各位端午节快乐呀!不好意思拖更两个月,最近实在是太忙了,也想不到有什么好玩的,之前介绍过了几个好玩的ai网站,非常适合新手尝鲜,但很多都有额度限制,而且还开始收费了&…

【C语言】内存你知多少?详解C语言动态内存管理

目录 一, 计算机中的内存 二,动态内存申请函数 2.1 头文件 2.2 malloc函数 2.3 free函数 2.3 calloc函数 2.4 realloc函数——调整空间函数 情况1:原有空间之后有足够大的空间 情况2:原有空间之后没有足够大的空间 2…

Android大图加载优化方案,避免程序OOM

我们在编写Android程序的时候经常要用到许多图片,不同图片总是会有不同的形状、不同的大小,但在大多数情况下,这些图片都会大于我们程序所需要的大小。比如微博长图,海报等等。所以我们就要对图片进行局部显示。 大图加载基本需求…

信号与系统复习笔记——信号与系统的时域和频域特性

信号与系统复习笔记——信号与系统的时域和频域特性 傅里叶变换的模和相位表示 一般来说,傅里叶变换的结果是复数,所以能够使用模和相位来表示,具体的有: X ( j ω ) ∣ X ( j ω ) ∣ e j ∡ X ( j ω ) X(j\omega) |X(j\ome…

浅尝Transformer和LLM

文章目录 TransformerTransformer的衍生BERTPre-trainingBERT与其他方法的关系怎么用BERT做生成式任务? GPTPre-trainingFine-Tuning Transformer工具开源库特点 LLM系列推理服务 大语言模型势不可挡啊。 哲学上来说,语言就是我们的一切,语言…

MySQL 高级(进阶) SQL 语句

创建两个表格 use awsl; create table location (Region char(20),Store_Name char(20)); insert into location values(East,Boston); insert into location values(East,New York); insert into location values(West,Los Angeles); insert into location values(West,Houst…

JMU20 软件工程经济学 复习总结

文章目录 碎碎念0. 基准收益率 i1. 现金流量图2. 净现值 NPV,内部收益率 IRR3. 单利,复利计算4. 等额年金NAV5. 动态回收期 P t ′ P_t Pt′​6. 固定资产折旧 [书P44]7. 增值税8. 软件行业增值税的即征即退9. 利息备付率 ICR,偿债备付率 DSC…

C语言之分支与循环

一、语句 什么是语句 C语言中,由一个分号( ;)隔开的即为一条语句。 这些都是语句: ( 一行里只有 ;的语句,我们称其为 “空语句” ) int main(void) {printf("hel…

UVM1.2究竟在UVM1.1上做了哪些升级

想必大家平时也没有很注意UVM1.1版本和UVM1.2版本的不同之处,只有在用一些以前UVM1.1能支持的功能,到了UVM1.2却出现编译报错,找不到对应的变量或者函数或者类的时候,才意识到这两个版本的差异。笔者也是遇到了1个打印问题&#x…

利用Django的视图类TemplateView将模板、视图与模板变量方便快速的整合在一起

TemplateView是Django提供的通用视图类之一,它允许您在不编写任何Python代码的情况下将模板与视图关联起来。下面是关于TemplateView类的一些介绍: 渲染模板:TemplateView负责渲染指定的模板并返回生成的HTML响应。您只需提供模板名称或路径即…