我一直在尝试在**Procedure ORACLE中寻找**distinct **的替代方案。 ** 你能给我建议吗,因为**DISTINCT **不能在Procedure中使用。
我用过listagg等各种函数,但是没有任何效果
不能在程序中使用。DISTINCT
是的,可以。
如果您有示例数据(包含重复行):
CREATE TABLE table_name (a, b) AS
SELECT 1, 1 FROM DUAL CONNECT BY LEVEL <= 3 UNION ALL
SELECT 1, 2 FROM DUAL CONNECT BY LEVEL <= 4 UNION ALL
SELECT 2, 1 FROM DUAL CONNECT BY LEVEL <= 2 UNION ALL
SELECT 2, 2 FROM DUAL CONNECT BY LEVEL <= 5;
然后:
DECLARE
PROCEDURE print_distinct_values
IS
BEGIN
FOR r IN (SELECT DISTINCT * FROM table_name) LOOP
DBMS_OUTPUT.PUT_LINE(r.a || ', ' || r.b);
END LOOP;
END;
BEGIN
DBMS_OUTPUT.ENABLE();
print_distinct_values();
END;
/
输出:
1, 1
1, 2
2, 1
2, 2
如果您想要相同的输出,那么您也可以使用查询(带或不带
PROCEDURE
):
SELECT a, b FROM table_name GROUP BY a, b
或:
SELECT a, b
FROM table_name
ORDER BY ROW_NUMBER() OVER (PARTITION BY a, b ORDER BY ROWNUM)
FETCH FIRST ROW WITH TIES
或:
SELECT a, b
FROM (
SELECT a, b,
ROW_NUMBER() OVER (PARTITION BY a, b ORDER BY ROWNUM) AS rn
FROM table_name
)
WHERE rn = 1
所有输出都相同。
幸运的猜测:正如您提到的LISTAGG,您是否尝试过使用
LISTAGG(DISTINCT ...)
但它不起作用?如果是这样,则意味着您的数据库版本不支持该语法;你必须在19c。
对于较低版本,请使用内联视图来获取不同的值,然后将
LISTAGG
应用于其结果集。
演示:这是11g:
SQL> select listagg(distinct job, ', ') within group (order by job) as result from emp;
select listagg(distinct job, ', ') within group (order by job) from emp
*
ERROR at line 1:
ORA-30482: DISTINCT option not allowed for this function
内联视图(第2行);我相信这就是您正在寻找的:
SQL> select listagg(job, ', ') within group (order by job) as result
2 from (select distinct job from emp);
RESULT
--------------------------------------------------------------------------------
ANALYST, CLERK, MANAGER, PRESIDENT, SALESMAN
SQL>
19c(支持
DISTINCT
内的LISTAGG
):
SQL> select listagg(distinct job, ', ') within group (order by job) as result from emp;
RESULT
--------------------------------------------------------------------------------
ANALYST, CLERK, MANAGER, PRESIDENT, SALESMAN
SQL>
如果我猜错了,没问题;我会修复这个答案,或者删除它。