我正在尝试检测分层表中的重复/重复值。
考虑以下(稍作设想)的例子:
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个值。
答案 0 :(得分:3)
试试这个..
SELECT EMPNO,ENAME FROM,count(*)as counts emp group by EMPNO,ENAME having count(*)>1
答案 1 :(得分: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);
答案 2 :(得分:0)
听起来你需要首先从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;
答案 3 :(得分:-1)
这很容易:
SELECT * FROM empstART with mgr IN (SELECT empno FROM emp WHERE ename = '琼斯'联盟所有人 SELECT empno FROM emp WHERE ename = 'JONES')先前连接empno = mgr;