当我尝试使用case表达式时,出现错误“ ORA-00937:不是单组功能”:
SELECT CASE
WHEN EXTRACT_TABLE IS NOT NULL
THEN
'SELECT '||LISTAGG((EXTRACT_TABLE||'.'||EXTRACT_COLONNE ||' AS " '|| EXTRACT_LIBELLE || ' " '),',') WITHIN GROUP(ORDER BY EXTRACT_ORDRE)
ELSE 'SELECT '||LISTAGG((EXTRACT_COLONNE ||' AS " '|| EXTRACT_LIBELLE || ' " '),',') WITHIN GROUP(ORDER BY EXTRACT_ORDRE)
END
不用大小写表达式就可以正常工作,
SELECT
'SELECT '||LISTAGG((EXTRACT_TABLE||'.'||EXTRACT_COLONNE ||' AS " '|| EXTRACT_LIBELLE || ' " '),',') WITHIN GROUP(ORDER BY EXTRACT_ORDRE)
但是我真的需要检查EXTRACT_TABLE
是否为空。我该如何解决?
谢谢
答案 0 :(得分:1)
在CASE
内使用LISTAGG
:
WITH sample AS (SELECT 1 AS EXTRACT_ORDRE, 'tab1' AS EXTRACT_TABLE, 'col1' AS EXTRACT_COLONNE, 'name1' AS EXTRACT_LIBELLE FROM DUAL
UNION ALL
SELECT 2, 'tab2', 'col2', 'name2' FROM DUAL
UNION ALL
SELECT 3, NULL, 'col3', 'name3' FROM DUAL
)
select 'SELECT '||LISTAGG(CASE WHEN EXTRACT_TABLE IS NOT NULL THEN (EXTRACT_TABLE||'.'||EXTRACT_COLONNE ||' AS " '|| EXTRACT_LIBELLE || ' " ')
ELSE EXTRACT_COLONNE ||' AS " '|| EXTRACT_LIBELLE || ' " ' END ,',') WITHIN GROUP(ORDER BY EXTRACT_ORDRE) AS result
from sample;
输出:
RESULT
-------------------
SELECT tab1.col1 AS " name1 " ,tab2.col2 AS " name2 " ,col3 AS " name3 "
答案 1 :(得分:0)
该错误表示您需要在group-by子句中包含extract_table
;或添加分组依据(如果您还没有),这可能涉及识别其他列,并可能影响输出。这取决于查询的其余部分和数据以及期望的结果。
您原来的非案例方法会在输出中留下不需要的时间段。例如,对于一些示例数据,使用CTE,您的查询将给出:
-- CTE for sample data
with cte (extract_table, extract_colonne, extract_libelle, extract_ordre) as (
select null, 'col1', 'label1', 2 from dual
union all
select 'tab42', 'col2', 'label2', 3 from dual
union all
select 'tab42', 'col3', 'label3', 1 from dual
)
-- actual query
SELECT
'SELECT '||LISTAGG((EXTRACT_TABLE||'.'||EXTRACT_COLONNE ||' AS " '|| EXTRACT_LIBELLE || ' " '),',') WITHIN GROUP(ORDER BY EXTRACT_ORDRE)
from cte;
SELECT tab42.col3 AS " label3 " ,.col1 AS " label1 " ,tab42.col2 AS " label2 "
您的case-expression方法带有一个附加的group by EXTRACT_TABLE
子句,可以将该数据分成两个结果:
-- CTE for sample data
with cte (extract_table, extract_colonne, extract_libelle, extract_ordre) as (
select null, 'col1', 'label1', 2 from dual
union all
select 'tab42', 'col2', 'label2', 3 from dual
union all
select 'tab42', 'col3', 'label3', 1 from dual
)
-- actual query
SELECT
CASE
WHEN EXTRACT_TABLE IS NOT NULL THEN
'SELECT '||LISTAGG((EXTRACT_TABLE||'.'||EXTRACT_COLONNE ||' AS " '|| EXTRACT_LIBELLE || ' " '),',') WITHIN GROUP(ORDER BY EXTRACT_ORDRE)
ELSE
'SELECT '||LISTAGG((EXTRACT_COLONNE ||' AS " '|| EXTRACT_LIBELLE || ' " '),',') WITHIN GROUP(ORDER BY EXTRACT_ORDRE)
END
from cte
group by EXTRACT_TABLE;
SELECT tab42.col3 AS " label3 " ,tab42.col2 AS " label2 "
SELECT col1 AS " label1 "
可能不是您想要的。但是,如果您实际上有一个过滤器,并确保所有选定的行都具有或不具有表名-而不是上面的混合表-那么这仍然可以使用。
另一种方法是只跳过表名,或更重要的是跳过将表名和列名分开的.
,进一步进入查询;也就是说,将'.'
替换为CASE WHEN EXTRACT_TABLE IS NOT NULL THEN '.'
,有条件地跳过了这段时间。当该列为null时,无论如何将没有名称部分,并且该表达式将取消句点,因此您只能获得该列的名称。
SELECT
'SELECT ' || LISTAGG((EXTRACT_TABLE
|| CASE WHEN EXTRACT_TABLE IS NOT NULL THEN '.' END
|| EXTRACT_COLONNE || ' AS " ' || EXTRACT_LIBELLE || ' " '), ',')
WITHIN GROUP(ORDER BY EXTRACT_ORDRE)
使用相同的示例数据获取一行,而没有无效的前置时间:
-- CTE for sample data
with cte (extract_table, extract_colonne, extract_libelle, extract_ordre) as (
select null, 'col1', 'label1', 2 from dual
union all
select 'tab42', 'col2', 'label2', 3 from dual
union all
select 'tab42', 'col3', 'label3', 1 from dual
)
-- actual query
SELECT
'SELECT ' || LISTAGG((EXTRACT_TABLE
|| CASE WHEN EXTRACT_TABLE IS NOT NULL THEN '.' END
|| EXTRACT_COLONNE || ' AS " ' || EXTRACT_LIBELLE || ' " '), ',')
WITHIN GROUP(ORDER BY EXTRACT_ORDRE)
from cte;
SELECT tab42.col3 AS " label3 " ,col1 AS " label1 " ,tab42.col2 AS " label2 "
答案 2 :(得分:0)
这是您的查询:
SELECT (CASE WHEN EXTRACT_TABLE IS NOT NULL
THEN <expression with LISTAGG()>
THEN <expression with LISTAGG()>
END)
FROM t;
由于LISTAGG()
,这是一个聚合查询。但是,没有 GROUP BY
。在这种情况下,所有列引用必须是聚合函数的参数。
我认为您的意思是其中之一:
SELECT (CASE WHEN EXTRACT_TABLE IS NOT NULL
THEN <expression with LISTAGG()>
THEN <expression with LISTAGG()>
END)
FROM t
GROUP BY EXTRACT_TABLE;
或者:
SELECT <expression with LISTAGG()>
FROM t
WHERE EXTRACT_TABLE IS NOT NULL
UNION ALL
SELECT <expression with LISTAGG()>
FROM t
WHERE EXTRACT_TABLE IS NULL;
您可能还打算进行条件聚合:
SELECT 'SELECT '|| LISTAGG((EXTRACT_TABLE || '.' || col_lib ||' AS " '|| EXTRACT_LIBELLE || ' " '), ',') WITHIN GROUP(ORDER BY EXTRACT_ORDRE)
FROM (SELECT (CASE WHEN EXTRACT_TABLE IS NOT NULL
THEN EXTRACT_COLONNE
ELSE EXTRACT_LIBELLE
END) as col_lib
t.*
FROM t
) t