Выбор строк с помощью оператора существования с использованием условий ИЛИ - PullRequest
0 голосов
/ 31 января 2020

Я хочу выбрать случаи из одной таблицы, где Code или DST или Short_text или long_text равны (в 2 или более строк) И ID не равны.

ID  Code    DST   Short_text      Long_text

1   B 01    B 1     Bez1           Bezirk1
1   B 01    B 1     Bez1           Bezirk1
2   B 02    B 2     Bez2           Bezirk2
3   B 03    B 3     Bez3           Bezirk3
4   B 04    B 4     Bez4           Bezirk4
4   B 04    B 4     Bez4           Bezirk4
5   B 05    B 5     Bez5           Bezirk5
6   B 06    B 6     Bez6           Bezirk6
7   B 07    B 7     Bez7           Bezirk7
8   B 08    B 8     Bez8           Bezirk8
9   B 09    B 9     Bez9           Bezirk9
97  M 51    M 52    MA 51          Sport  
96  M 51    M 51    MA 51          Sport 

И я хочу получить следующий результат:

97  M 51    M 52    MA 51          Sport  
96  M 51    M 51    MA 51          Sport 

потому что у них разные ID, но у них одинаковый код ИЛИ SImilar Short_text ИЛИ simmlar long_text.

Вот что я пробовал:

select
ID,
CODE,
DST,
Short_text,
Long_text,
from Main_table tbl
where load_date = (select max(load_date) from Main_table)
and  exists
(
select 1 from Main_table
where
tbl.ID != ID
and (tbl.CODE = CODE
or tbl.DST = DST
or tbl.short_text = short_text
or tbl.long_text = long_text)
);

Но это не дает мне желаемого результата. У вас есть идеи, как я могу улучшить свой запрос?

Ответы [ 4 ]

1 голос
/ 31 января 2020

Вы можете использовать функции analyti c, чтобы избежать самостоятельного объединения:

Oracle Настройка :

CREATE TABLE table_name ( ID, Code, DST, Short_text, Long_text ) as
 select  1,   'B 01',    'B 1',     'Bez1', 'Bezirk1' from dual union all
 select  1,   'B 01',    'B 1',     'Bez1', 'Bezirk1' from dual union all
 select  2,   'B 02',    'B 2',     'Bez2', 'Bezirk2' from dual union all 
 select  3,   'B 03',    'B 3',     'Bez3', 'Bezirk3' from dual union all
 select  4,   'B 04',    'B 4',     'Bez4', 'Bezirk4' from dual union all
 select  4,   'B 04',    'B 4',     'Bez4', 'Bezirk4' from dual union all
 select  5,   'B 05',    'B 5',     'Bez5', 'Bezirk5' from dual union all 
 select  6,   'B 06',    'B 6',     'Bez6', 'Bezirk6' from dual union all
 select  7,   'B 07',    'B 7',     'Bez7', 'Bezirk7' from dual union all
 select  8,   'B 08',    'B 8',     'Bez8', 'Bezirk8' from dual union all 
 select  9,   'B 09',    'B 9',     'Bez9', 'Bezirk9' from dual union all
 select 97,   'M 51',    'M 52',     'MA 51', 'Sport' from dual union all
 select 96,   'M 51',    'M 52',     'MA 51', 'Sport' from dual;

Запрос :

SELECT ID, Code, DST, Short_text, Long_text
FROM   (
  SELECT t.*,
         COUNT( DISTINCT id ) OVER ( PARTITION BY code       ) AS num_code,
         COUNT( DISTINCT id ) OVER ( PARTITION BY dst        ) AS num_dst,
         COUNT( DISTINCT id ) OVER ( PARTITION BY short_text ) AS num_short_text,
         COUNT( DISTINCT id ) OVER ( PARTITION BY long_text  ) AS num_long_text
  FROM   table_name t
)
WHERE  num_code > 1
OR     num_dst  > 1
OR     num_short_text > 1
OR     num_long_text > 1

Выход :

ID | CODE | DST  | SHORT_TEXT | LONG_TEXT
-: | :--- | :--- | :--------- | :--------
96 | M 51 | M 52 | MA 51      | Sport    
97 | M 51 | M 52 | MA 51      | Sport    

db <> скрипка здесь

1 голос
/ 31 января 2020

Вы можете использовать агрегацию count(*), содержащую предложения having последовательно:

select ID, Code, DST, Short_text, Long_text
  from Main_table
 where (Code, DST, Short_text, Long_text) in
       (select Code, DST, Short_text, Long_text
          from Main_table
         group by Code, DST, Short_text, Long_text
        having count(*) > 1)
 group by ID, Code, DST, Short_text, Long_text
having count(*) = 1

или count(*) over (partition by...) analyti c функция, которая будет рассматриваться, включая предложения раздела с и без столбца ID:

with m2 as
(
select m.*,
       count(*) over ( partition by Code, DST, Short_text, Long_text ) as cnt1,
       count(*) over ( partition by ID, Code, DST, Short_text, Long_text ) as cnt2
  from Main_table m
)
select ID, Code, DST, Short_text, Long_text
  from m2
 where cnt1 > 1 and cnt2 = 1 

Демо

1 голос
/ 31 января 2020

Это было бы

SQL> select * from main_table;

        ID CODE DST  SHORT LONG_TE
---------- ---- ---- ----- -------
         1 B 01 B 1  Bez1  Bezirk1
         1 B 01 B 1  Bez1  Bezirk1
         2 B 02 B 2  Bez2  Bezirk2
         3 B 03 B 3  Bez3  Bezirk3
         4 B 04 B 4  Bez4  Bezirk4
         4 B 04 B 4  Bez4  Bezirk4
         5 B 05 B 5  Bez5  Bezirk5
         6 B 06 B 6  Bez6  Bezirk6
         7 B 07 B 7  Bez7  Bezirk7
         8 B 08 B 8  Bez8  Bezirk8
         9 B 09 B 9  Bez9  Bezirk9
        97 M 51 M 52 MA 51 Sport
        96 M 51 M 51 MA 51 Sport

13 rows selected.

SQL> select a.*
  2    from main_table a
  3         join main_table b
  4            on     a.id <> b.id
  5               and (   a.code = b.code
  6                    or a.dst = b.dst
  7                    or a.short_text = b.short_text
  8                    or a.long_text = b.long_text);

        ID CODE DST  SHORT LONG_TE
---------- ---- ---- ----- -------
        97 M 51 M 52 MA 51 Sport
        96 M 51 M 51 MA 51 Sport

SQL>
0 голосов
/ 31 января 2020

Вы можете использовать ниже запрос

select mt1.ID, mt1.Code, mt1.DST, mt1.Short_text, mt1.Long_text from main_table as mt1 
Cross Apply(
select * from main_table as mt2 where mt1.id!= mt2.id and ( mt1.code=mt2.code or mt1.short_text =mt2.short_text or mt1.long_text = mt2.long_text )
) cv
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...