我有一个查询,当我尝试聚合它时,它达到了 2000 个字符的限制,并且我想获取尽可能多的元素。
所以数据看起来像这样
id | 总结 | 优先 |
---|---|---|
a | 文字 | 1 |
a | 去 | 2 |
a | 这里 | 3 |
b | 不受影响 | 1 |
假设我用“,”连接字段并且长度限制为 10 个字符,我希望生成这样的结果
id | 总结 |
---|---|
a | 文字,出发 |
b | 不受影响 |
而不是“发短信,到这里”。
您已经了解了截断溢出的可能性。子字符串will返回缩短结果,但如果单词在中间被“剪切”,则可能看起来丑陋。这里有一个函数可以很好地做到这一点,注意单词的结尾并连接省略号(
...
)(如果字符串实际上比你得到的长)。
SQL> CREATE OR REPLACE
2 FUNCTION f_trim_text (par_tekst IN VARCHAR2, par_len IN NUMBER)
3 RETURN VARCHAR2
4 IS
5 l_str_1 VARCHAR2 (4000); -- trim PAR_TEKST to PAR_LEN length
6 l_space_pos NUMBER; -- position of the 2nd space in L_STR_1 from end of the string
7 retval VARCHAR2 (4000);
8 BEGIN
9 IF par_tekst IS NULL
10 OR par_len <= 0
11 THEN
12 retval := NULL;
13 ELSIF LENGTH (par_tekst) < par_len
14 THEN
15 retval := par_tekst;
16 ELSE
17 l_str_1 := SUBSTR (par_tekst, 1, par_len);
18 l_space_pos := INSTR (l_str_1, ' ', -1);
19 retval := SUBSTR (l_str_1, 1, l_space_pos) || ' ...';
20 END IF;
21
22 RETURN retval;
23 END f_trim_text;
24 /
Function created.
它是如何工作的?
SQL> select deptno,
2 listagg(ename, ', ' on overflow truncate) as emps,
3 substr (listagg(ename, ', ' on overflow truncate), 1, 15) as substr_emps,
4 f_trim_text(listagg(ename, ', ' on overflow truncate), 15 ) as trimmed_emps
5 from emp
6 group by deptno;
DEPTNO EMPS SUBSTR_EMPS TRIMMED_EMPS
---------- -------------------------------------------------- -------------------- --------------------
30 ALLEN, WARD, MARTIN, BLAKE, TURNER, JAMES ALLEN, WARD, MA ALLEN, WARD, ...
10 CLARK, KING, MILLER CLARK, KING, MI CLARK, KING, ...
20 SMITH, JONES, SCOTT, ADAMS, FORD SMITH, JONES, S SMITH, JONES, ...
SQL>