在聚合函数中获取不是单个组函数的错误
Getting error of not a single group function in aggregated function
CREATE TABLE test1 (
e_id NUMBER(1),
e_ques_id NUMBER(10)
);
INSERT INTO test1 VALUES(1,3);
INSERT INTO test1 VALUES(1,4);
CREATE TABLE test_ref (
code NUMBER(1),
c_value VARCHAR2(20)
);
INSERT INTO test_ref VALUES(3,'May');
INSERT INTO test_ref VALUES(4,2022);
COMMIT;
Tool Used: SQL Developer(18c)
有两个 tables test1
和 test_ref
我想从 test_ref
table 中获取值以便将月份和年份列值。
预期输出:
+------+------------+
| e_id | month_year |
+------+------------+
| 1 | May 2022 |
+------+------------+
我的尝试:
SELECT t.e_id,
LISTAGG(c_value,' ')month_year
FROM test1 t
JOIN test_ref tr ON(t.e_ques_id = tr.code)
WHERE t.e_ques_id IN(3,4)
GROUP BY t.e_id;
这为我提供了我正在寻找的确切结果,但我需要在现有视图中添加此逻辑,我需要使用聚合或案例表达式来获取结果。因此我尝试使用 CASE
和 MAX
但它给我一个错误,不是单个组函数
我的尝试(导致错误):
SELECT t.e_id,
MAX(CASE
WHEN t.e_ques_id IN(3,4) THEN LISTAGG(c_value,' ')
END )month_year
FROM test1 t
JOIN test_ref tr ON(t.e_ques_id = tr.code)
GROUP BY t.e_id;
对我来说,很难猜测为什么现有视图需要聚合函数或case
表达式。
无论如何:如果您在其分析形式中使用 max
,请跳过 case
表达式,而是将 e_ques_id
条件移动到 where
子句中(因为您已经在查询中做了 works),你会得到这个:
SQL> SELECT t.e_id,
2 MAX (LISTAGG (c_value, ' ') WITHIN GROUP (ORDER BY code))
3 OVER (ORDER BY NULL) month_year
4 FROM test1 t JOIN test_ref tr ON t.e_ques_id = tr.code
5 WHERE t.e_ques_id IN (3, 4)
6 GROUP BY t.e_id;
E_ID MONTH_YEAR
---------- ---------------
1 May 2022
SQL>
我不知道这是否会(或不会)在该视图中起作用,但是 - 您可以尝试一下。
你可以在里面使用条件聚合 LISTAGG
:
SELECT t.e_id,
LISTAGG(CASE WHEN t.e_ques_id IN (3,4) THEN c_value END, ' ')
WITHIN GROUP (ORDER BY t.e_ques_id) AS month_year
FROM test1 t
JOIN test_ref tr ON(t.e_ques_id = tr.code)
GROUP BY t.e_id;
其中,对于示例数据:
CREATE TABLE test1 (e_id, e_ques_id) AS
SELECT 1, LEVEL FROM DUAL CONNECT BY LEVEL <= 5;
CREATE TABLE test_ref (code, c_value) AS
SELECT 1, 'Not this' FROM DUAL UNION ALL
SELECT 3, 'May' FROM DUAL UNION ALL
SELECT 4, '2022' FROM DUAL UNION ALL
SELECT 5, 'Not this either' FROM DUAL;
输出:
E_ID
MONTH_YEAR
1
May 2022
db<>fiddle here
这是你可以使用 Max() OVER() 的方法,虽然我不明白你想做什么,但也许这可以帮助...
WITH
test1 AS
(
SELECT 1 "E_ID", 3 "E_QUES_ID" FROM DUAL UNION ALL
SELECT 1 "E_ID", 4 "E_QUES_ID" FROM DUAL UNION ALL
SELECT 1 "E_ID", 5 "E_QUES_ID" FROM DUAL UNION ALL
SELECT 1 "E_ID", 6 "E_QUES_ID" FROM DUAL
),
test_ref AS
(
SELECT 3 "CODE", 'May' "C_VALUE" FROM DUAL UNION ALL
SELECT 4 "CODE", '2022' "C_VALUE" FROM DUAL UNION ALL
SELECT 5 "CODE", 'Jun' "C_VALUE" FROM DUAL UNION ALL
SELECT 6 "CODE", '2022' "C_VALUE" FROM DUAL
)
SELECT
E_ID,
Max(LISTAGG(MY, ' ') WITHIN GROUP (ORDER BY E_ID, E_QUES_ID)) OVER() "MONTH_YEAR"
FROM
(
SELECT
t.E_ID,
t.E_QUES_ID,
CASE WHEN t.E_QUES_ID IN(3, 4) THEN tr.C_VALUE END "MY"
FROM
test1 t
INNER JOIN
test_ref tr ON(t.E_QUES_ID = tr.CODE)
ORDER BY
t.E_ID,
t.E_QUES_ID
)
GROUP BY
E_ID
CREATE TABLE test1 (
e_id NUMBER(1),
e_ques_id NUMBER(10)
);
INSERT INTO test1 VALUES(1,3);
INSERT INTO test1 VALUES(1,4);
CREATE TABLE test_ref (
code NUMBER(1),
c_value VARCHAR2(20)
);
INSERT INTO test_ref VALUES(3,'May');
INSERT INTO test_ref VALUES(4,2022);
COMMIT;
Tool Used: SQL Developer(18c)
有两个 tables test1
和 test_ref
我想从 test_ref
table 中获取值以便将月份和年份列值。
预期输出:
+------+------------+
| e_id | month_year |
+------+------------+
| 1 | May 2022 |
+------+------------+
我的尝试:
SELECT t.e_id,
LISTAGG(c_value,' ')month_year
FROM test1 t
JOIN test_ref tr ON(t.e_ques_id = tr.code)
WHERE t.e_ques_id IN(3,4)
GROUP BY t.e_id;
这为我提供了我正在寻找的确切结果,但我需要在现有视图中添加此逻辑,我需要使用聚合或案例表达式来获取结果。因此我尝试使用 CASE
和 MAX
但它给我一个错误,不是单个组函数
我的尝试(导致错误):
SELECT t.e_id,
MAX(CASE
WHEN t.e_ques_id IN(3,4) THEN LISTAGG(c_value,' ')
END )month_year
FROM test1 t
JOIN test_ref tr ON(t.e_ques_id = tr.code)
GROUP BY t.e_id;
对我来说,很难猜测为什么现有视图需要聚合函数或case
表达式。
无论如何:如果您在其分析形式中使用 max
,请跳过 case
表达式,而是将 e_ques_id
条件移动到 where
子句中(因为您已经在查询中做了 works),你会得到这个:
SQL> SELECT t.e_id,
2 MAX (LISTAGG (c_value, ' ') WITHIN GROUP (ORDER BY code))
3 OVER (ORDER BY NULL) month_year
4 FROM test1 t JOIN test_ref tr ON t.e_ques_id = tr.code
5 WHERE t.e_ques_id IN (3, 4)
6 GROUP BY t.e_id;
E_ID MONTH_YEAR
---------- ---------------
1 May 2022
SQL>
我不知道这是否会(或不会)在该视图中起作用,但是 - 您可以尝试一下。
你可以在里面使用条件聚合 LISTAGG
:
SELECT t.e_id,
LISTAGG(CASE WHEN t.e_ques_id IN (3,4) THEN c_value END, ' ')
WITHIN GROUP (ORDER BY t.e_ques_id) AS month_year
FROM test1 t
JOIN test_ref tr ON(t.e_ques_id = tr.code)
GROUP BY t.e_id;
其中,对于示例数据:
CREATE TABLE test1 (e_id, e_ques_id) AS
SELECT 1, LEVEL FROM DUAL CONNECT BY LEVEL <= 5;
CREATE TABLE test_ref (code, c_value) AS
SELECT 1, 'Not this' FROM DUAL UNION ALL
SELECT 3, 'May' FROM DUAL UNION ALL
SELECT 4, '2022' FROM DUAL UNION ALL
SELECT 5, 'Not this either' FROM DUAL;
输出:
E_ID MONTH_YEAR 1 May 2022
db<>fiddle here
这是你可以使用 Max() OVER() 的方法,虽然我不明白你想做什么,但也许这可以帮助...
WITH
test1 AS
(
SELECT 1 "E_ID", 3 "E_QUES_ID" FROM DUAL UNION ALL
SELECT 1 "E_ID", 4 "E_QUES_ID" FROM DUAL UNION ALL
SELECT 1 "E_ID", 5 "E_QUES_ID" FROM DUAL UNION ALL
SELECT 1 "E_ID", 6 "E_QUES_ID" FROM DUAL
),
test_ref AS
(
SELECT 3 "CODE", 'May' "C_VALUE" FROM DUAL UNION ALL
SELECT 4 "CODE", '2022' "C_VALUE" FROM DUAL UNION ALL
SELECT 5 "CODE", 'Jun' "C_VALUE" FROM DUAL UNION ALL
SELECT 6 "CODE", '2022' "C_VALUE" FROM DUAL
)
SELECT
E_ID,
Max(LISTAGG(MY, ' ') WITHIN GROUP (ORDER BY E_ID, E_QUES_ID)) OVER() "MONTH_YEAR"
FROM
(
SELECT
t.E_ID,
t.E_QUES_ID,
CASE WHEN t.E_QUES_ID IN(3, 4) THEN tr.C_VALUE END "MY"
FROM
test1 t
INNER JOIN
test_ref tr ON(t.E_QUES_ID = tr.CODE)
ORDER BY
t.E_ID,
t.E_QUES_ID
)
GROUP BY
E_ID