Oracle -为什么我不能排除length(listagg(somecolumn))> xxx的行

pftdvrlh  于 7个月前  发布在  Oracle
关注(0)|答案(2)|浏览(77)

我似乎无法解决这个问题:(
我运行一个查询,返回一些结果,但在这些结果中,我需要过滤出这个客户没有超过240个字符的自由文本注解
不幸的是,数据存储的方式是笔记被分成多行:

NOTE_NUMBER    LINE_NUMBER    NOTE_TEXT
123            1              ABC
123            2              DEFGHIJ
456            1              ABCDEE

字符串
etc NOTE_NUMBER是返回到另一个表的主键我已经知道如何为每个NOTE_NUMBER返回一个结果行

SELECT A.NOTE_NUMBER, LISTAGG(NOTE_TEXT)
FROM TABLE TABLE 1 A
JOIN TABLE 2 B ON A.NOTE_NUMBER = B.NOTE_NUMBER
GROUP BY A.NOTE_NUMBER


这使我返回:

123 ABCDEFGHIJ
456 ABCDEE


太棒了!但是现在说我只想返回LENGTH(LISTAGG(NOTE_TEXT))< 7的行,这就是我被难倒的地方。
我已经看到这个工程更改我的查询:

SELECT A.NOTE_NUMBER, LISTAGG(NOTE_TEXT), LENGTH(LISTAGG(NOTE_TEXT))
FROM TABLE TABLE 1 A
JOIN TABLE 2 B ON A.NOTE_NUMBER = B.NOTE_NUMBER
GROUP BY A.NOTE_NUMBER


现在给我:

123 ABCDEFGHIJ 11
456 ABCDEE 7


但是如果我想在so中加入where子句:

SELECT A.NOTE_NUMBER, LISTAGG(NOTE_TEXT), LENGTH(LISTAGG(NOTE_TEXT))
FROM TABLE TABLE 1 A
JOIN TABLE 2 B ON A.NOTE_NUMBER = B.NOTE_NUMBER
WHERE LENGTH(LISTAGG(NOTE_TEXT)) < 7
GROUP BY A.NOTE_NUMBER


我得到一个错误

ORA-00934 group function is not allowed here


所以我的搜索让我使用了CASE:

SELECT A.NOTE_NUMBER, CASE WHEN LENGTH(LISTAGG(NOTE_TEXT)) < 7 THEN LISTAGG(NOTE_TEXT) END
FROM TABLE TABLE 1 A
JOIN TABLE 2 B ON A.NOTE_NUMBER = B.NOTE_NUMBER
GROUP BY A.NOTE_NUMBER


但是,这仍然返回2行

123 NULL
456 ABCDEE


当我尝试在注解长度> 7个字符的情况下执行不存在时,这对我没有好处,因为两行仍然会返回,因此NOTE_NUMBER键仍然会匹配回另一个表
我试图找出如何排除行,如果该情况是空的,也不能弄清楚!
所有我需要的是这个查询返回的是这样的:

456 ABCDEE


请帮帮我!非常感谢!

332nm8kg

332nm8kg1#

一种选择是将查询放在CTE或子查询中(我在这里不重复该查询,因为其他答案显示了它)。
另一种选择是在GROUP BY子句中使用HAVING
尝试失败的原因是不能在WHERE子句中使用像LISTAGG这样的聚合函数。
使用HAVING,你可以使用它!

SELECT 
  t1.NOTE_NUMBER, 
  LISTAGG(t1.NOTE_TEXT) AS wholeText, 
  LENGTH(LISTAGG(t1.NOTE_TEXT)) AS wholeLength
FROM table1 t1
INNER JOIN table2 t2 
  ON t1.NOTE_NUMBER = t2.NOTE_NUMBER
GROUP BY t1.NOTE_NUMBER
  HAVING LENGTH(LISTAGG(t1.NOTE_TEXT)) < 7;

字符串
在此sample fiddle上尝试这两个选项

zu0ti5jz

zu0ti5jz2#

这相当简单-使用query(that works)作为另一个select语句的 source(无论是CTE还是子查询),它只使用你已经收集的内容:

WITH
   temp
   AS
      (  SELECT a.note_number,
                LISTAGG (note_text) note_text,
                LENGTH (LISTAGG (note_text)) note_len
           FROM table1 a JOIN table2 b ON a.note_number = b.note_number
       GROUP BY a.note_number)
SELECT *
  FROM temp
 WHERE note_len < 7

字符串

相关问题