sql - Pivot 不适用于聚合 clob 列
问题描述
我有如下数据
ID COUNT COL1 COL_CLOB
12345 5 a (HUGE_CLOB)
12345 8 b (HUGE_CLOB)
我想要像下面这样的输出
ID a_count a_COL_CLOB b_COUNT b_COL_CLOB
12345 5 (HUGE_CLOB) 8 (HUGE_CLOB)
我在查询中使用 xmlagg,因为 COL_CLOB 大小超过 4000 个字符,而 listagg 不支持,pivot 不适用于聚合 clob 列。好心提醒
解决方案
您可以定义自己的函数来聚合CLOB
值:
CREATE OR REPLACE TYPE CLOBAggregation AS OBJECT(
value CLOB,
STATIC FUNCTION ODCIAggregateInitialize(
ctx IN OUT CLOBAggregation
) RETURN NUMBER,
MEMBER FUNCTION ODCIAggregateIterate(
self IN OUT CLOBAggregation,
value IN CLOB
) RETURN NUMBER,
MEMBER FUNCTION ODCIAggregateTerminate(
self IN OUT CLOBAggregation,
returnValue OUT CLOB,
flags IN NUMBER
) RETURN NUMBER,
MEMBER FUNCTION ODCIAggregateMerge(
self IN OUT CLOBAggregation,
ctx IN OUT CLOBAggregation
) RETURN NUMBER
);
/
CREATE OR REPLACE TYPE BODY CLOBAggregation
IS
STATIC FUNCTION ODCIAggregateInitialize(
ctx IN OUT CLOBAggregation
) RETURN NUMBER
IS
BEGIN
ctx := CLOBAggregation( NULL );
RETURN ODCIConst.SUCCESS;
END;
MEMBER FUNCTION ODCIAggregateIterate(
self IN OUT CLOBAggregation,
value IN CLOB
) RETURN NUMBER
IS
BEGIN
IF value IS NULL THEN
NULL;
ELSIF self.value IS NULL THEN
self.value := value;
ELSE
self.value := self.value || ',' || value;
END IF;
RETURN ODCIConst.SUCCESS;
END;
MEMBER FUNCTION ODCIAggregateTerminate(
self IN OUT CLOBAggregation,
returnValue OUT CLOB,
flags IN NUMBER
) RETURN NUMBER
IS
BEGIN
returnValue := self.value;
RETURN ODCIConst.SUCCESS;
END;
MEMBER FUNCTION ODCIAggregateMerge(
self IN OUT CLOBAggregation,
ctx IN OUT CLOBAggregation
) RETURN NUMBER
IS
BEGIN
IF self.value IS NULL THEN
self.value := ctx.value;
ELSIF ctx.value IS NULL THEN
NULL;
ELSE
self.value := self.value || ',' || ctx.value;
END IF;
RETURN ODCIConst.SUCCESS;
END;
END;
/
CREATE FUNCTION CLOB_AGG( value CLOB )
RETURN CLOB
PARALLEL_ENABLE AGGREGATE USING CLOBAggregation;
/
然后,对于样本数据:
CREATE TABLE table_name ( id NUMBER, "COUNT" NUMBER, col1 VARCHAR2(5), col_clob CLOB );
DECLARE
p_clob CLOB;
BEGIN
p_clob := EMPTY_CLOB() || LPAD( 'a', 4000, 'a' ) || LPAD( 'a', 10, 'a' );
INSERT INTO table_name VALUES ( 12345, 5, 'a', p_clob );
p_clob := EMPTY_CLOB() || LPAD( 'b', 4000, 'b' ) || LPAD( 'b', 10, 'b' );
INSERT INTO table_name VALUES ( 12345, 8, 'b', p_clob );
END;
/
然后,您可以使用条件聚合:
SELECT id,
MAX( CASE col1 WHEN 'a' THEN "COUNT" END ) AS a_count,
CLOB_AGG( CASE col1 WHEN 'a' THEN col_clob END ) AS a_col_clob,
MAX( CASE col1 WHEN 'b' THEN "COUNT" END ) AS b_count,
CLOB_AGG( CASE col1 WHEN 'b' THEN col_clob END ) AS b_col_clob
FROM table_name
GROUP BY id
哪个输出:
身份证 | A_COUNT | A_COL_CLOB | B_COUNT | B_COL_CLOB ----: | ------: | :-------------------- | ------: | :-------------------- 12345 | 5 | aaaaa<4000 更多>aaaaa | 8 | bbbb<4000 更多>bbbb
db<>在这里摆弄
推荐阅读
- android - 由于缺少 JAR 签名,Android Studio 不允许我上传 APK
- ember.js - 尝试将 Ember 2.14.2 更新到 Ember 2.18.2 时出错
- web-services - 如何在短时间内从 GAE 服务轮询 Web 服务?
- c# - 使用数据行测试是否可以在构建时对 TestCategory 进行过滤?
- flutter - 颤振行将一项放在开始,另一项放在中间
- java - 波纹效果在 Android 9(Api 28,Pie)上无法正常工作
- sql-server - SQL Server:字符串连接句柄
- python - 对带有 Doubles 的 python 中的属性 getter/setter 的期望
- java - 自动装配在 Junit 测试和 spring @configuration 中失败
- reactjs - 反应 this.setState 不适用于上下文 API