【问题标题】:Find duplicate/repeated rows in hierarchical sql在分层 sql 中查找重复/重复的行
【发布时间】:2009-07-14 20:41:48
【问题描述】:

我正在尝试检测分层表中的重复值。

考虑以下(稍微做作的)示例:

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 个值。

【问题讨论】:

    标签: sql oracle hierarchical-data


    【解决方案1】:

    试试这个..

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

    【讨论】:

    • 我想说这是做这种事情的典型方式,使用“有”sql关键字。
    【解决方案2】:

    复制结果集的一种方法是将其交叉连接(笛卡尔积)到具有两行的结果集,即:

    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】:

      听起来您需要先从 emp 到复杂选择查询的结果进行外部联接,然后基于此进行连接查询。

      可能是这样的:

      与经理作为( 选择 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 连接 = 经理;

      【讨论】:

        【解决方案4】:

        很简单:

        选择 *FROM empSTART WITH mgr IN (选择 empno 从 emp WHERE ename = 'JONES' UNION ALL
        选择 empno 从 emp WHERE ename = 'JONES') 由 PRIOR empno = 经理连接;

        【讨论】:

        • UNION ALL 没有帮助....在 IN 的评估过程中,重复的值被抑制了。
        猜你喜欢
        • 2023-03-31
        • 1970-01-01
        • 1970-01-01
        • 2012-01-02
        • 1970-01-01
        • 2016-09-29
        • 2011-02-05
        • 1970-01-01
        相关资源
        最近更新 更多