2009-07-14 77 views
5

我試圖在分層表中檢測重複/重複的值。在分層表中查找重複/重複的行

考慮以下(稍微)例如:

SELECT * 
FROM emp 
START WITH mgr IN (SELECT empno FROM emp WHERE ename = 'JONES' 
        UNION ALL 
        SELECT empno FROM emp WHERE ename = 'JONES') 
CONNECT BY PRIOR empno = mgr; 

返回...

 EMPNO ENAME  JOB    MGR HIREDATE   SAL  COMM  DEPTNO 
---------- ---------- --------- ---------- --------- ---------- ---------- ---------- 
     7788 SCOTT  ANALYST   7566 19-APR-87  3000     20 
     7876 ADAMS  CLERK   7788 23-MAY-87  1100     20 
     7902 FORD  ANALYST   7566 03-DEC-81  3000     20 
     7369 SMITH  CLERK   7902 17-DEC-80  800     20 

什麼其實我想要的是......

 EMPNO ENAME  JOB    MGR HIREDATE   SAL  COMM  DEPTNO 
---------- ---------- --------- ---------- --------- ---------- ---------- ---------- 
     7788 SCOTT  ANALYST   7566 19-APR-87  3000     20 
     7788 SCOTT  ANALYST   7566 19-APR-87  3000     20 
     7876 ADAMS  CLERK   7788 23-MAY-87  1100     20 
     7876 ADAMS  CLERK   7788 23-MAY-87  1100     20 
     7369 SMITH  CLERK   7902 17-DEC-80  800     20 
     7369 SMITH  CLERK   7902 17-DEC-80  800     20 
     7902 FORD  ANALYST   7566 03-DEC-81  3000     20 
     7902 FORD  ANALYST   7566 03-DEC-81  3000     20 

即我希望每個行將返回與子查詢中存在的次數相同的次數(忽略次序)。由於START WITH正在使用IN子句,所以重複的值將被抑制。是否有可能重新組織SQL,以便我可以這樣做?

請注意,在我的情況下,子小節不是UNION,而是一個SELECT,它可能會從表中返回多個(可能是重複的)值。

我可以在PL/SQL中通過將值寫入臨時表然後GROUPing + COUNTing來實現,但我希望只在可能的情況下在SQL中執行。

如果需要澄清,請告訴我。

感謝:-)

編輯:

注意,有可能是0,...,N值從子查詢返回。

回答

-1

它很容易:

SELECT * FROM與經理 empSTART IN (SELECT EMPNO FROM EMP WHERE爲ename = 'JONES' UNION ALL
SELECT EMPNO FROM EMP WHERE爲ename = 'JONES' )CONNECT BY PRIOR empno = mgr;複製一個結果集

+0

的UNION ALL沒有幫助....重複的值在在評價過程中surpressed。 – cagcowboy 2009-07-14 20:53:04

0

一種方式是交叉連接(笛卡爾乘積),它有兩個行的結果集,即:

SQL> WITH your_query AS (
    2  SELECT object_name 
    3  FROM all_objects WHERE ROWNUM <= 3 
    4 ) 
    5 SELECT your_query.* 
    6 FROM your_query 
    7 CROSS JOIN (SELECT NULL FROM dual UNION ALL SELECT NULL FROM dual); 

OBJECT_NAME 
------------------------------ 
IND$ 
IND$ 
ICOL$ 
ICOL$ 
OBJ$ 
OBJ$ 

你的情況,這應該工作:

WITH your_query AS (
    SELECT * 
    FROM emp 
    START WITH mgr IN (SELECT empno FROM emp WHERE ename = 'JONES') 
      CONNECT BY PRIOR empno = mgr 
) 
SELECT your_query.* 
    FROM your_query 
CROSS JOIN (SELECT NULL FROM dual UNION ALL SELECT NULL FROM dual); 
3

試試這個..

SELECT EMPNO,ENAME FROM,count(*)as counts emp group by EMPNO,ENAME having count(*)>1 
+1

我會說這是使用「有」sql關鍵字做這種事情的典型方式。 – djangofan 2009-07-16 17:00:55

0

聽起來像是你需要冷杉t從emp執行外連接到複雜選擇查詢的結果,然後將連接查詢基於此。

事情是這樣的,也許:

 
WITH mgrs AS (
    SELECT empno FROM emp WHERE ename = 'JONES' 
    UNION ALL 
    SELECT empno FROM emp WHERE ename = 'JONES' 
), 
all_emps AS (
    SELECT emp.*, 
      CASE WHEN mgrs.empno IS NOT NULL THEN 1 END AS start_with 
    FROM emp 
    LEFT OUTER JOIN mgrs ON mgrs.empno = emp.mgr 
) 
SELECT * 
FROM all_emps 
START WITH start_with = 1 
CONNECT BY PRIOR empno = mgr;