2015-07-02 3 views
0

Привет У меня есть таблица с двумя столбцами (WID, DT) с данными ..Oracle Пересечение строк в таблице

WID DT 
------- 
A 10 
A 11 
A 12 
B 10 
B 11 
C 10 
C 13 

Если я передать выход, В на входе я должен получить как 10 и 11 Пересечение DT. Если я передаю вход A, B, C, я должен получить 10 в качестве вывода. Если я передаю A как вход, тогда 10,11,12 в качестве вывода .. Мой вход будет динамическим, зависит от некоторых условий от пользовательского интерфейса. Как добиться этого в запросе ...

ответ

0

Вы можете попробовать, как показано ниже, используя Oracle INTERSECT SET Operator

select DT from table1 
where WID in ('A') 
INTERSECT 
select DT from table1 
where WID in ('B'); 
1

Вот способ, который не требует от вас, чтобы добавить Intersect для каждого элемента в списке, вы перейдите в качестве параметра. Я не могу гарантировать, что он будет хорошо отображаться на больших наборах данных, поэтому вам придется протестировать свои данные!

Это первый пример показывает результаты, которые имитируют эффект нескольких значений параметра передается в то же время (в основном, чтобы показать вам результаты различных тестов вы упомянули):

with sample_data as (select 'A' WID, 10 DT from dual union all 
        select 'A' WID, 11 DT from dual union all 
        select 'A' WID, 12 DT from dual union all 
        select 'B' WID, 10 DT from dual union all 
        select 'B' WID, 11 DT from dual union all 
        select 'C' WID, 10 DT from dual union all 
        select 'C' WID, 13 DT from dual), 
      params as (select 'A, B, C' val from dual union all 
        select 'A, B' val from dual union all 
        select 'A, C' val from dual union all 
        select 'B, C' val from dual union all 
        select 'A' val from dual union all 
        select 'B' val from dual union all 
        select 'C' val from dual), 
    pivot_params as (select val, 
          trim(regexp_substr(val, '[^,]+', 1, level)) sub_val, 
          regexp_count(val||',', ',') num_vals 
        from params 
        connect by prior val = val 
           and level <= regexp_count(val||',', ',') 
           and prior dbms_random.value is not null), 
     results as (select sd.*, 
          pp.*, 
          count(distinct wid) over (partition by pp.val, sd.dt) cnt_of_distinct_wid_per_val 
        from sample_data sd 
          inner join pivot_params pp on (sd.wid = pp.sub_val)) 
select distinct val param, 
       dt 
from results 
where num_vals = cnt_of_distinct_wid_per_val 
order by 1, 2; 


PARAM   DT 
------- ---------- 
A    10 
A    11 
A    12 
A, B   10 
A, B   11 
A, B, C   10 
A, C   10 
B    10 
B    11 
B, C   10 
C    10 
C    13 

Этот второй пример намного ближе к тому, что вам нужно передать в параметре с одним значением - вам явно не нужен подзапрос sample_data (вы просто используете свое имя таблицы вместо того, где sample_data используется в основном запрос), и вам придется заменить: param на имя параметра, которое вы используете в своем коде, но, надеюсь, вы увидите, что вам нужно изменить, чтобы заставить его работать в вашем коде:

with sample_data as (select 'A' WID, 10 DT from dual union all 
        select 'A' WID, 11 DT from dual union all 
        select 'A' WID, 12 DT from dual union all 
        select 'B' WID, 10 DT from dual union all 
        select 'B' WID, 11 DT from dual union all 
        select 'C' WID, 10 DT from dual union all 
        select 'C' WID, 13 DT from dual), 
    -- end of mimicking your data 
    pivot_param as (select :param val, 
          trim(regexp_substr(:param, '[^,]+', 1, level)) sub_val, 
          regexp_count(:param||',', ',') num_vals 
        from dual 
        connect by level <= regexp_count(:param||',', ',')), 
     results as (select sd.*, 
          pp.*, 
          count(distinct wid) over (partition by pp.val, sd.dt) cnt_of_distinct_wid_per_val 
        from sample_data sd 
          inner join pivot_param pp on (sd.wid = pp.sub_val)) 
select distinct val param, 
       dt 
from results 
where num_vals = cnt_of_distinct_wid_per_val 
order by 1, 2; 

ETA: способ, которым это работает: во-первых, превратить ваш список как параметр в фиктивную таблицу, с одной строкой на элемент в списке, а также количеством элементов, которые вы передали в . (NB. Я не принял во внимание тот случай, когда вы дважды ввели один и тот же элемент в мой запрос - вам нужно изменить способ определения количества элементов в подзапросе pivot_params (возможно, используя count(distinct(...) over (...)) и убедиться, что вывод был отличным.)

Как только вы преобразовали свой список параметров в таблицу, вы можете присоединиться к нему в таблице, содержащей ваши данные (в моих запросах выше, это будет подзапрос sample_data) и узнать, сколько уникальных WID есть на DT. Если счетчик совпадает с количеством элементов в списке параметров, вы знаете, что все элементы сопоставлены.

+0

Прошу прощения, я могу дать вам +1 здесь, но на самом деле lacs and crores of +1 для вас. –

Смежные вопросы