ORACLE过程中DISTINCT的替换函数

问题描述 投票:0回答:2

我一直在尝试在**Procedure ORACLE中寻找**distinct **的替代方案。 ** 你能给我建议吗,因为**DISTINCT **不能在Procedure中使用。

我用过listagg等各种函数,但是没有任何效果

sql oracle plsql
2个回答
0
投票

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

所有输出都相同。

小提琴


0
投票

幸运的猜测:正如您提到的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>

如果我猜错了,没问题;我会修复这个答案,或者删除它。

© www.soinside.com 2019 - 2024. All rights reserved.