2014-02-21 49 views
1
..... 
temp Varchar2 (20); 
e_name Varchar2 (255); 
..... 

Begin 

e_name := e_name || temp; 

Dbms_Output.Put_Line('names: ' || e_name); 

Output result 
------------- 
names: 'John', 'Sam', 'David', 'Sam', 'John', 'Alex' 

删除重复的数据如何格式化我e_name除去重复的名字,让我有输出结果的Oracle PL SQL字符串

required result 
------------- 
names: 'John', 'Sam', 'David', 'Alex' 

回答

1

那么你可以修改你的程序是这样

Begin 
e_name := e_name || temp; 
SELECT listagg (names, ',') within GROUP (ORDER BY rn) 
    INTO e_name 
    FROM 
    (
     SELECT level rn, 
       regexp_substr (e_name, '[^,]+', 1, level) names, 
       row_number () over (partition BY regexp_substr (e_name, '[^,]+', 1, level) order by level) rnn 
      FROM dual 
      CONNECT BY regexp_substr (e_name, '[^,]+', 1, level) IS NOT NULL 
) 
    WHERE rnn = 1; 

Dbms_Output.Put_Line('names: ' || e_name); 

最内层查询会将列表转换为行,然后外层查询将过滤并重新创建字符串。

0

这可以在纯SQL中完成,但会变得有点混乱,特别是如果您使用11gR2之前的listagg()。既然你在PL/SQL领土是已经,这里是消除在一个简单的PL/SQL时尚复本的解决方案:

declare e_name varchar2(255) := q'"'John', 'Sam', 'David', 'Sam', 'John', 'Alex'"'; 
     new_ename varchar2(255) := substr(e_name,1,instr(e_name,'''',2)); 
begin 
dbms_output.put_line ('e_name: ' || e_name); 
for i in 1..length(e_name) - length(replace(e_name,',')) loop 
    if instr(new_ename, 
     substr(e_name,instr(e_name,', ',1,i),instr(e_name||', ',', ',1,i+1) - instr(e_name,', ',1,i))) = 0 
    then 
     new_ename := new_ename || substr(e_name,instr(e_name,', ',1,i),instr(e_name||', ',', ',1,i+1) - instr(e_name,', ',1,i)); 
    end if; 
end loop; 
dbms_output.put_line ('new_ename: ' || new_ename); 
end; 


e_name: 'John', 'Sam', 'David', 'Sam', 'John', 'Alex' 
new_ename: 'John', 'Sam', 'David', 'John', 'Alex' 
0

有一种叫做ASSOCIATIVE阵列,它作为在Java中哈希表。我们可以将分隔文本放入散列表中,从而可以消除重复项。

我们在这里使用EXISTS收集方法来检查值是否已经存在!

这是一个简单的阅读没有SQL类型的解决方案。所以,表演之一。

DECLARE 
    e_name VARCHAR2 (4000) := 'the text goes here'; 
    L_TEMP_TEXT VARCHAR2(4000); 
    V_LOOPCOUNT NUMBER :=0; 
    T_WORD VARCHAR2(4000); 
    T_FINAL_TEXT VARCHAR2(4000) := ' '; 

    --Declare a DICT like a Hash table 
    TYPE DICT IS TABLE OF VARCHAR2(4000) INDEX BY VARCHAR(4000); 
    MYDICT DICT; 
BEGIN 
     L_TEMP_TEXT := regexp_replace(e_name,'[,]+',','); -- Replace multiple consecutive commas as single 
     LOOP 
     v_LOOPCOUNT := v_LOOPCOUNT+1; 
     T_WORD  := REGEXP_SUBSTR(e_name, '[^,]+', 1, V_LOOPCOUNT); 
     --In a loop we tokenize the String using comma as delimiter 
     EXIT WHEN T_WORD IS NULL; 

     IF NOT MYDICT.EXISTS(T_WORD) THEN 
      -- It is like a Hash Table, if not exists add to it. 
      MYDICT(T_WORD) := T_WORD; 
      T_FINAL_TEXT : T_FINAL_TEXT || ',' || T_WORD; 
     END; 
     END LOOP; 
     T_FINAL_TEXT := TRIM(BOTH ',' FROM TRIM(T_FINAL_TEXT)); 
     -- Trimming the unwanted commas 

     DBMS_OUTPUT.PUT_LINE('after removing duplicates : ' || T_FINAL_TEXT); 
EXCEPTION 
    WHEN OTHERS THEN 
     DBMS_OUTPUT.PUT_LINE(sqlerrm||chr(10)||dbms_utility.format_error_backtrace); 
END; 
/
1

更换WM_CONCAT与LISTAGG - 我跑Oragle 10g中,LISTAGG是11克:

SELECT wm_concat(ename) AS employees 
    FROM emp_test 
WHERE deptno = 20 
/

Output - SMITH repeats twice: 
    SMITH,JONES,SCOTT,ADAMS,FORD,SMITH 

SELECT wm_concat(distinct ename) AS employees 
FROM emp_test 
WHERE deptno = 20 
/

The distinct fixes the problem: 
    ADAMS,FORD,JONES,SCOTT,SMITH