Удалить дубликаты записей с ROWNUM? - PullRequest
0 голосов
/ 22 сентября 2018

Я знаю, как удалить дубликаты записей с ROWID.

Помогите мне удалить дубликаты записей с ROWNUM в Oracle.

1 Ответ

0 голосов
/ 22 сентября 2018

Это просто не сработает.Из документации :

Для каждой строки, возвращаемой запросом, псевдостолбец ROWNUM возвращает число, указывающее порядок, в котором Oracle выбирает строку из таблицы или набора соединенных строк.Первая выбранная строка имеет ROWNUM, равный 1, вторая - 2 и т. Д.

Его значение устанавливается в момент запуска запроса и может быть изменено в зависимости от того, как вы извлекаете данные (другое ORDER BY будет выдавать другое значение ROWNUM для одной и той же строки).Поскольку он последовательный, вы не можете установить «группы» значений ROWNUM (например, чтобы из одного набора было выбрано 1, 2, 3, а для другого 1, 2, 3, 4, 5 - выВы всегда получите 1, 2, 3, 4, 5, 6, 7, 8).

Если вы планируете сделать что-то вроде этого:

SQL> create table test as
  2    select e.empno, e.deptno, d.dname, e.ename
  3    from emp e join dept d on e.deptno = d.deptno;

Table created.

SQL> select * from test order by deptno;

     EMPNO     DEPTNO DNAME          ENAME
---------- ---------- -------------- ----------
      7782         10 ACCOUNTING     CLARK
      7839         10 ACCOUNTING     KING
      7934         10 ACCOUNTING     MILLER
      7369         20 RESEARCH       SMITH
      7902         20 RESEARCH       FORD
      7566         20 RESEARCH       JONES
      7900         30 SALES          JAMES
      7844         30 SALES          TURNER
      7654         30 SALES          MARTIN
      7521         30 SALES          WARD
      7499         30 SALES          ALLEN
      7698         30 SALES          BLAKE

12 rows selected.

SQL> delete from test t
  2  where t.empno in (select a.empno
  3                    from (select t1.empno, t1.deptno, t1.dname, rownum rn
  4                          from test t1
  5                         ) a
  6                    where a.rn > 1
  7                   );

11 rows deleted.

Как видите,все строки (кроме одной) являются дубликатами.И вот почему:

SQL> rollback;

Rollback complete.

SQL> select a.deptno, a.empno, a.rn, a.rn1
  2  from (select t1.empno, t1.deptno, t1.dname, rownum rn,
  3               row_number() over (partition by t1.deptno order by null) rn1
  4        from test t1
  5       ) a;

    DEPTNO      EMPNO         RN        RN1
---------- ---------- ---------- ----------
        10       7782          2          1
        10       7839          1          2
        10       7934          3          3
        20       7369          5          1
        20       7902          4          2
        20       7566          6          3
        30       7900          7          1
        30       7844          8          2
        30       7654          9          3
        30       7521         10          4
        30       7499         11          5
        30       7698         12          6

12 rows selected.

Видите?RN (ROWNUM) имеет все значения от 1, 2, ..., 12. RN1 (ROW_NUMBER, который позволяет нам устанавливать разделы) выполняет работу правильно.Итак, если бы вы использовали RN1 вместо RN, это сработало бы:

SQL> delete from test t
  2  where t.empno in (select a.empno
  3                    from (select t1.empno, t1.deptno, t1.dname, rownum rn,
  4                          row_number() over (partition by t1.deptno order by null) rn1
  5                          from test t1
  6                         ) a
  7                    where a.rn1 > 1
  8                   );

9 rows deleted.

SQL> select * From test;

     EMPNO     DEPTNO DNAME          ENAME
---------- ---------- -------------- ----------
      7782         10 ACCOUNTING     CLARK
      7369         20 RESEARCH       SMITH
      7900         30 SALES          JAMES

SQL>

[EDIT: удаление дубликатов # 2]

Вот еще один пример, который показывает, как /что делать, если вы хотите удалить дубликаты.Он основан на «методике ROWID» (хотя есть и другие).

Вернуться к таблице, с которой мы работали.Предположим, что мы хотим сохранить только одну отдельную работу для каждого отдела:

SQL> select deptno, job, dname, empno, ename
  2  from test
  3  order by deptno, job;

    DEPTNO JOB       DNAME               EMPNO ENAME
---------- --------- -------------- ---------- ----------
        10 CLERK     ACCOUNTING           7934 MILLER
        10 MANAGER   ACCOUNTING           7782 CLARK
        10 PRESIDENT ACCOUNTING           7839 KING

        20 ANALYST   RESEARCH             7902 FORD
        20 CLERK     RESEARCH             7369 SMITH
        20 MANAGER   RESEARCH             7566 JONES

        30 CLERK     SALES                7900 JAMES
        30 MANAGER   SALES                7698 BLAKE
        30 SALESMAN  SALES                7844 TURNER    -- leave
        30 SALESMAN  SALES                7654 MARTIN    -- only
        30 SALESMAN  SALES                7521 WARD      -- one
        30 SALESMAN  SALES                7499 ALLEN     -- salesman

12 rows selected.
  • в отделе 10, дубликатов нет - 3 сотрудника, каждый из которых выполняет свою работу
  • то же самое касается отдела 20
  • , однако в отделе 30 есть 4 ПРОДАВЦА, и мы хотим оставить только одного - остальные являются дубликатами

Itозначает, что при удалении строк необходимо учитывать оба столбца - DEPTNO и JOB.Давайте сделаем это:

SQL> delete from test a
  2  where rowid > (select min(rowid)
  3                 from test b
  4                 where a.deptno = b.deptno  --> take both DEPTNO ...
  5                   and a.job = b.job        --> and JOB into account
  6                );

3 rows deleted.

Результат: отделы 10 и 20 не изменились, но в отделе 30 теперь у нас только один продавец, как мы и хотели:

SQL> select deptno, job, dname, empno, ename
  2  from test
  3  order by deptno, job;

    DEPTNO JOB       DNAME               EMPNO ENAME
---------- --------- -------------- ---------- ----------
        10 CLERK     ACCOUNTING           7934 MILLER
        10 MANAGER   ACCOUNTING           7782 CLARK
        10 PRESIDENT ACCOUNTING           7839 KING
        20 ANALYST   RESEARCH             7902 FORD
        20 CLERK     RESEARCH             7369 SMITH
        20 MANAGER   RESEARCH             7566 JONES
        30 CLERK     SALES                7900 JAMES
        30 MANAGER   SALES                7698 BLAKE
        30 SALESMAN  SALES                7844 TURNER

9 rows selected.

SQL>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...