powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Убрать записи двойники
36 сообщений из 36, показаны все 2 страниц
Убрать записи двойники
    #39361318
IgorD
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый день!
Зашел в тупик, прошу помощи.
Упрощенная модель задачи. В таблице есть два поля id1 и id2. Записи, в которых id1 || id2 = id2 || id1 считаются "двойниками" и нужно одну из них убрать (любую)

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
with s as
 (select 1 as id1,
         2 as id2
    from dual
  union all
  select 3 as id1,
         4 as id2
    from dual
  union all
  select 5 as id1,
         6 as id2
    from dual
  union all
  select 2 as id1,
         1 as id2
    from dual
  union all
  select 4 as id1,
         3 as id2
    from dual
  union all
  select 7 as id1,
         8 as id2
    from dual
  union all
  select 9 as id1,
         0 as id2
    from dual
 )

select *
from s



Результат

ID1 ID2 1 2 3 4 5 6 2 1 4 3 7 8 9 0

Нужно что бы осталось

ID1 ID2 1 2 3 4 5 6 7 8 9 0
...
Рейтинг: 0 / 0
Убрать записи двойники
    #39361326
londinium
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
IgorD,
Если не путаю, то отловить их можно так:
Код: sql
1.
2.
3.
SELECT T.ID1, T.ID2,T1.ID1,T1.ID2
FROM TABLEA T
JOIN  TABLEA T1 ON T.ID1=T1.ID2 AND T.ID2=T1.ID1
...
Рейтинг: 0 / 0
Убрать записи двойники
    #39361330
IgorD
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
londinium,
отловить не проблема. У меня был такой вариант

Код: plsql
1.
2.
3.
4.
...
select *
from s
where s.id1 || s.id2  in (select t.id2 || t.id1  from s t )



Нужно убрать по одной записи у двойников, а как, не знаю...
...
Рейтинг: 0 / 0
Убрать записи двойники
    #39361338
Фотография env
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
less + group by + min
...
Рейтинг: 0 / 0
Убрать записи двойники
    #39361340
Фотография AmKad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
IgorD,

Нужно вывести уникальную пару select-ом или удалить дубли из таблицы?
...
Рейтинг: 0 / 0
Убрать записи двойники
    #39361345
IgorD
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AmKad,

Нужно построить select таким образом, что бы там не было дублей.
...
Рейтинг: 0 / 0
Убрать записи двойники
    #39361347
IgorD
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
... т.е. из двух дублирующих строк осталась одна (любая)
...
Рейтинг: 0 / 0
Убрать записи двойники
    #39361353
Фотография AmKad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plsql
1.
2.
select distinct least(id1, id2), greatest(id1, id2)
from s


+ если есть null-ы, то допилишь сам.
...
Рейтинг: 0 / 0
Убрать записи двойники
    #39361357
Фотография orawish
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
IgorD,


Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
with s as
 (select 1 as id1,
         2 as id2
    from dual
  union all
  select 3 as id1,
         4 as id2
    from dual
  union all
  select 5 as id1,
         6 as id2
    from dual
  union all
  select 2 as id1,
         1 as id2
    from dual
  union all
  select 4 as id1,
         3 as id2
    from dual
  union all
  select 7 as id1,
         8 as id2
    from dual
  union all
  select 9 as id1,
         0 as id2
    from dual
 )
select least(id1,id2) a,greatest(id1,id2) b -- ,count(*) c
from s
group by least(id1,id2) ,greatest(id1,id2);

...
Рейтинг: 0 / 0
Убрать записи двойники
    #39361359
IgorD
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
СПАСИБО!!!
...
Рейтинг: 0 / 0
Убрать записи двойники
    #39361361
Фотография -2-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
least/greatest сменит ориентацию некоторым бирюкам.
...
Рейтинг: 0 / 0
Убрать записи двойники
    #39361363
Фотография AmKad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Без смены ориентации
Код: plsql
1.
2.
3.
4.
5.
6.
select id1, id2
from
   (select s.*, row_number() over (partition by least(id1, id2), greatest(id1, id2) order by id1, id2) rn
    from s
   )
where rn = 1;
...
Рейтинг: 0 / 0
Убрать записи двойники
    #39361379
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
IgorD
Код: plsql
1.
s.id1 || s.id2

Это шутка?
...
Рейтинг: 0 / 0
Убрать записи двойники
    #39361401
IgorD
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Elic,

это не решение, это подход, который оказался ошибочным. :) Знаю, что так делать нельзя
...
Рейтинг: 0 / 0
Убрать записи двойники
    #39361403
IgorD
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если серьезно, то было так to_char(id1) || ' -' || to_char(id2)
...
Рейтинг: 0 / 0
Убрать записи двойники
    #39361517
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
-2-least/greatest сменит ориентацию некоторым бирюкам.

Только если оная присутствует (намек на NULL для тех кто не понял).

SY.
...
Рейтинг: 0 / 0
Убрать записи двойники
    #39361576
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
IgorDЕсли серьезно, то было так to_char(id1) || ' -' || to_char(id2)Т.е. про expression list не слыхал?
...
Рейтинг: 0 / 0
Убрать записи двойники
    #39361795
IgorD
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ElicIgorDЕсли серьезно, то было так to_char(id1) || ' -' || to_char(id2)Т.е. про expression list не слыхал?
Не буду лгать - не использовал на практике. Почитал документацию, покрутил с вышеизложенным примером - не получилось.
Буду рад, если выложите рабочий вариант, и я узнаю что-то новое для себя :)
Спасибо.
...
Рейтинг: 0 / 0
Убрать записи двойники
    #39361805
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
IgorDпокрутилПродемонстрируй.
...
Рейтинг: 0 / 0
Убрать записи двойники
    #39361814
IgorD
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ElicIgorDпокрутилПродемонстрируй.
Код: plsql
1.
2.
3.
4.
5.
6.
select *
from s 
group by grouping sets
  ((id1, id2),
   (id2, id1)
  )
...
Рейтинг: 0 / 0
Убрать записи двойники
    #39361819
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пробуй здесь:IgorD
Код: plsql
1.
where s.id1 || s.id2  in (select t.id2 || t.id1  from s t )
...
Рейтинг: 0 / 0
Убрать записи двойники
    #39362076
IgorD,
Может я не понял вопрос, но что мешает написать что-то вроде:
Код: plsql
1.
2.
3.
4.
5.
6.
SELECT * FROM
( запрос к таблице s, возвращающий все "двойники" )
WHERE id1 < id2
UNION ALL
SELECT * FROM
( запрос к таблице s, возвращающий все, кроме "двойников" )
...
Рейтинг: 0 / 0
Убрать записи двойники
    #39362181
Сергей Арсеньев
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
IgorD,

Давайте все-таки определимся 1,1111 и 11,111 это двойники? Я понимаю, что по условиям упрощенной задачи это так, но вдруг в оригинале нет. А может и да... :)
...
Рейтинг: 0 / 0
Убрать записи двойники
    #39362380
IgorD
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сергей Арсеньев,
Двойники считаются те строки в который одинаковые Id, в независимости от их размещения в колонках, т.е.
1 и 1111 двойники с 1111 и 1
...
Рейтинг: 0 / 0
Убрать записи двойники
    #39362384
IgorD
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Нетянепонял,
Из двойников/тройников/... нужно оставить только одну запись
...
Рейтинг: 0 / 0
Убрать записи двойники
    #39362385
IgorD
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
в реальной задаче я решил задачу с помощью решения от AmKad
Код: plsql
1.
row_number() over (partition by least(id1, id2), greatest(id1, id2) order by id1, id2) rn
...
Рейтинг: 0 / 0
Убрать записи двойники
    #39362603
IgorD,
ну да, одна запись и остается. Возвращает именно то, что хотелось:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
SELECT * FROM
( select *
from s
where s.id1 || s.id2  in (select t.id2 || t.id1  from s t ) )
WHERE id1 < id2
UNION
SELECT * FROM
( select *
from s
where s.id1 || s.id2 not  in (select t.id2 || t.id1  from s t ) )


А "тройники" - это что? О них речи не шло.
...
Рейтинг: 0 / 0
Убрать записи двойники
    #39362656
IgorD
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НетянепонялIgorD,
А "тройники" - это что? О них речи не шло.

Имел ввиду любое количество записей с одинаковыми id

И таки да :) - ваш вариант решает задачу
...
Рейтинг: 0 / 0
Убрать записи двойники
    #39362658
Фотография AmKad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
IgorDИ таки да :) - ваш вариант решает задачуНо, как уже намекали, только на ограниченном множестве допустимых значений.
...
Рейтинг: 0 / 0
Убрать записи двойники
    #39362675
IgorD
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Нетянепонял

Вашу идею преобразил в такой вид и остался доволен :)

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
with s as
 ( 
  select 1 as id1,
          1 as id2
    from dual
  union all
  select 1 as id1,
          1 as id2
    from dual
  union all
  select 1 as id1,
          2 as id2
    from dual
  union all
  select 1 as id1,
          2 as id2
    from dual
  union all
  select 3 as id1,
          4 as id2
    from dual
  union all
  select 5 as id1,
          6 as id2
    from dual
  union all
  select 2 as id1,
          1 as id2
    from dual
  union all
  select 4 as id1,
          3 as id2
    from dual
  union all
  select 7 as id1,
          8 as id2
    from dual
  union all
  select 9 as id1,
          0 as id2
    from dual)

select *
  from (select *
          from s
         where exists (select ''
                  from s t
                 where t.id2 = s.id1
                   and t.id1 = s.id2))
 where id1 <= id2
 
union

select *
  from (select *
          from s
         where not exists (select ''
                  from s t
                 where t.id2 = s.id1
                   and t.id1 = s.id2))

...
Рейтинг: 0 / 0
Убрать записи двойники
    #39362682
IgorD
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AmKadIgorDИ таки да :) - ваш вариант решает задачуНо, как уже намекали, только на ограниченном множестве допустимых значений.

Согласен. Меня радует множество вариантов решения задачи и огорчает, что я самостоятельно не нашел ни одного )
...
Рейтинг: 0 / 0
Убрать записи двойники
    #39362695
stax..
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НетянепонялIgorD,
ну да, одна запись и остается. Возвращает именно то, что хотелось :
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
SELECT * FROM
( select *
from s
where s.id1 || s.id2  in (select t.id2 || t.id1  from s t ) )
WHERE id1 < id2
UNION
SELECT * FROM
( select *
from s
where s.id1 || s.id2 not  in (select t.id2 || t.id1  from s t ) )


А "тройники" - это что? О них речи не шло.

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
  1  with s as(
  2  select 11111 id1,1 id2 from dual union all
  3  select 1 id1,11111 id2 from dual union all
  4  select 1111 id1,11 id2 from dual union all
  5  select 111 id1,111 id2 from dual union all
  6  select 111 id1,111 id2 from dual union all
  7  select 33 id1,33 id2 from dual union all
  8  select 33 id1,33 id2 from dual union all
  9  select 333 id1,3 id2 from dual union all
 10  select 11 id1,1111 id2 from dual
 11  )
 12  SELECT * FROM
 13  ( select *
 14  from s
 15  where s.id1 || s.id2  in (select t.id2 || t.id1  from s t ) )
 16  WHERE id1 < id2
 17  UNION
 18  SELECT * FROM
 19  ( select *
 20  from s
 21* where s.id1 || s.id2 not  in (select t.id2 || t.id1  from s t ) )
SQL> /

       ID1        ID2
---------- ----------
         1      11111
        11       1111



....
stax
...
Рейтинг: 0 / 0
Убрать записи двойники
    #39362715
IgorD
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stax..,

авторs.id1 || s.id2 - это не решение, это подход. Тут главное идея. А в реальной задаче лучше использовать или exists или в крайнем случае s.id1 || '-' || s.id2
...
Рейтинг: 0 / 0
Убрать записи двойники
    #39362720
Фотография AmKad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
IgorDА в реальной задаче лучше использовать или existsСчитал, сколько обращений к таблице выполняет оптимизатор этом случае?
...
Рейтинг: 0 / 0
Убрать записи двойники
    #39362730
IgorD
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AmKad,

в своей задаче я остановился на применение аналитической функции row_number().
А вот с exists действительно надо бы проверить. Не задумывался.
...
Рейтинг: 0 / 0
Убрать записи двойники
    #39362786
stax..
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
IgorDAmKadпропущено...
Но, как уже намекали, только на ограниченном множестве допустимых значений.

Согласен. Меня радует множество вариантов решения задачи и огорчает, что я самостоятельно не нашел ни одного )

мой варіант (мож уже и было)
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
  1  with s as(
  2  select 11111 id1,1 id2 from dual union all
  3  select 1 id1,11111 id2 from dual union all
  4  select 1111 id1,11 id2 from dual union all
  5  select 111 id1,111 id2 from dual union all
  6  select 111 id1,111 id2 from dual union all
  7  select 33 id1,33 id2 from dual union all
  8  select 33 id1,33 id2 from dual union all
  9  select 333 id1,3 id2 from dual union all
 10  select 11 id1,1111 id2 from dual
 11  )
 12  select min(id1) i1,max(id2) i2 from s
 13* group by least(id1,id2), greatest(id1,id2)
SQL> /

        I1         I2
---------- ----------
        33         33
       333          3
        11       1111
         1      11111
       111        111



.....
stax
...
Рейтинг: 0 / 0
36 сообщений из 36, показаны все 2 страниц
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Убрать записи двойники
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]