2014-10-14 13 views
1

Образец данных:PL/SQL - Сравнение наборов строк

ID  VALUE 
1001  A 
1001  B 
1002  A 
1002  A 
1003  A 
1003  B 

Стандарт сравнения ID = 1001

Отсюда, я хочу посмотреть на все другие идентификаторы = 1001 ... Я необходимо удостовериться:

  1. Каждый другой набор записей, сгруппированных по ID, имеет такое же количество связанных строк. В этом примере каждый проходит этот тест.
  2. Для каждого значения, связанного с ID = 1001, необходимо найти ТОЧНОЕ соответствие для всех других идентификаторов. В этом примере 1002 будет терпеть неудачу, потому что хотя оно имеет правильное количество строк, оно имеет два значения «A» и значение «B» .

Логически - это кажется достаточно простым ... но я уже несколько лет бил головой о клавиатуру.

Любая мудрость или помощь в группах будут оценены по достоинству.

С уважением,

Майк

ответ

1

Вот один из способов сделать первый запрос:

select s.id 
from sample s 
where s.id <> 101 
group by s.id 
having count(*) = (select count(*) from sample s where id = 101); 

Второй похож. Приближается следующее:

select s.id 
from sample s full outer join 
    (select s.* 
     from sample s 
     where s.id = 101 
    ) s100 
    on s.value = s100.vaue 
where s.id <> 101 
group by s.id 
having count(*) = count(s.value) and count(s.value) = count(s100.value); 

Проблема с этим запросом заключается в наличии дубликатов. Чтобы исправить это, нам нужно перечислить значения для каждого идентификатора:

select s.id 
from (select s.*, row_number() over (partition by s.id, s.value order by s.id) as seqnum 
     from sample s 
    ) s full outer join 
    (select s.*, row_number() over (partition by s.id, s.value order by s.id) as seqnum 
     from sample s 
     where s.id = 101 
    ) s100 
    on s.value = s100.vaue and s.seqnum = s100.seqnum 
where s.id <> 101 
group by s.id 
having count(*) = count(s.value) and count(s.value) = count(s100.value); 
+0

Как вы ее через 4 минуты ??? –

+1

@MaheswaranRavisankar. , , Вероятно, было много вырезания и вставки, но самым полезным курсом, который я получил в старшей школе, была сенсорная типизация. –

+0

Гордон - спасибо за то, что я вошел. Я ценю тщательную мысль. В основном это сработало, но он не заметил, когда один набор имел несколько строк, но соразмерные данные в любом случае. Я закончил делать что-то с listagg, чтобы сгладить строки в список CSV. Гросс ... но эффективный. –

0

Это может быть сделано без PL/SQL

with base_values as (
    select id, value 
    from the_table 
    where id = 1001 
), other_values as (
    select id, value 
    from the_table 
    where id <> 1001 
) 
select ov.id 
from base_values bv 
    join other_values ov on bv.value = ov.value 
group by ov.id 
having count(distinct ov.value) = (select count(distinct value) from base_values) 
+0

Лошадь Доу - спасибо за помощь. Как и в случае с решением Гордона, я получил от меня большую часть пути. Не каждый случай использования был покрыт, но вы оба указали мне в правильном направлении. Для записи я использовал несколько предложений WITH, чтобы закрыть меня, а затем INNER JOIN после агрегации. Уродливый - но это сработало. И так как это одноразовый запрос, чтобы вырезать некоторые несоответствующие данные, которые МОГУТ быть там с производства, я не беспокоюсь о симпатии. –

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