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,它可以从表中返回多个(可能是重复的)值。

我可以通过将值写入临时表然后进行 GROUPing + COUNTing 来在 PL/SQL 中执行此操作,但我更愿意仅在可能的情况下在 SQL 中执行此操作。

让我知道是否需要任何澄清。

谢谢 :-)

编辑:

请注意,子查询可能返回 0...N 个值。

4

4 回答 4

3

试试这个..

SELECT  EMPNO,ENAME FROM,count(*)as counts   emp group by EMPNO,ENAME having count(*)>1
于 2009-07-16T09:17:41.067 回答
0

听起来您需要首先从 emp 到您的复杂选择查询的结果进行外部联接,然后将 connect-by 查询建立在此基础上。

像这样的东西,也许:

与经理作为(
   选择 empno 从 emp WHERE ename = 'JONES'
   联合所有
   选择 empno 从 emp WHERE ename = 'JONES'
),
all_emps AS (
   选择雇员*,
          当 mgrs.empno 不为 NULL THEN 1 END AS start_with 时的情况  
   来自雇员
   左外连接 mgrs on mgrs.empno = emp.mgr
)
选择 *
FROM all_emps
从 start_with = 1 开始
通过先前的 empno 连接 = 经理;
于 2009-07-16T14:23:36.050 回答
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);
于 2009-07-16T07:49:31.713 回答
-1

这很容易:

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

于 2009-07-14T20:43:22.693 回答