2016-04-26 5 views
0

Я пытаюсь выполнить SQL-разделение с использованием Oracle, так что все User_ID, которые учат классы SAME как определенный ID, должны быть возвращены.SQL-запрос для выполнения деления

Таблица структуры обеих таблиц, я работаю с:

HUMAN(id, first, last) 
INSTRUCTOR(human_id, location) -- PK(id, location) 
CLASS(instructor_id, class_code, class_num) -- PK(instructor_id, class_code, class_num) 

Query Я сейчас работаю с:

SELECT DISTINCT instructor_id, class_code, class_num 
FROM CLASS 
WHERE NOT EXISTS (
    (SELECT instructor_id, class_code, class_num FROM CLASS) 
    MINUS 
    (SELECT instructor_id, class_code, class_num 
    FROM CLASS 
    WHERE instructor_id = 
    (SELECT HUMAN.id 
    FROM HUMAN 
    WHERE first = 'Foo' 
    AND last = 'Bar'))) 

Примеры данных

HUMAN 
id first last 
1 foo  bar 
2 John Doe 

INSTRUCTOR 
human_id location 
     1 US 
     2 CA 

CLASS 
instructor_id class_code class_num 
    1    CS   999 
    1    MA   111 
    1    DE   222 
    2    CS   999 
    2    MA   111 
    2    DE   222 
    3    CS   999 
    4    CS   999 

запрос должен return instructor_id 2, так как он является единственным, который инструктирует те же классы, что и instructor_id 1

Запрос, который у меня есть, не содержит строки, несмотря на то, что данные вставляются в соответствии с этим сценарием.

+0

Что «тот же класс» означает один и тот же код класса или тот же класс num или оба? В вашем примере существует взаимно-однозначное соотношение между двумя столбцами, но, предположительно, в ваших реальных данных это не так (возможно, class_num отражает как class_code, так и семестр? или место нахождения? - в противном случае почему бы и то?) – mathguy

+0

То же самое классное, как class_code, так и class_num – hello

ответ

0
SELECT DISTINCT instructor_id, class_code, class_num 
FROM CLASS 
WHERE class_num IN (SELECT class_num from CLASS WHERE instructor_id = (SELECT HUMAN.id FROM HUMAN WHERE first = 'Foo' AND last = 'Bar')) 

Это вернет всех инструкторов (в том числе Foo Bar), которые дают тот же класс, что и Foo Bar.

Если вы хотите исключить Foo Bar, просто добавьте еще один класс WHERE (instructor_id! = (SELECT HUMAN.id ИЗ ЧЕЛОВЕЧЕСКОГО где впервые = 'Foo' И последнее, = 'Бар'))

+0

Этот запрос возвращает все 'instructionor_id', который инструктирует хотя бы один из классов, заданный' foo bar' – hello

0

Один из способов : данные и выход

with t as (
    select distinct instructor_id id, class_num cn 
    from class 
    where instructor_id = (select id from human 
          where first = 'foo' and last = 'bar')) 
select c.instructor_id as id, max(h.first||' '||h.last) as name 
    from class c 
    join human h on c.instructor_id = h.id 
    join t on t.cn = c.class_num and c.instructor_id <> t.id 
    group by instructor_id 
    having count(distinct class_num) = (select count(1) from t) 

Тест:

create table HUMAN (id number(3), first varchar2(5), last varchar2(5)); 
insert into human values (1, 'foo', 'bar'); 
insert into human values (2, 'John', 'Doe'); 

create table INSTRUCTOR (human_id number(3), location varchar2(3)); 
insert into instructor values (1, 'US'); 
insert into instructor values (2, 'CA'); 

create table CLASS (instructor_id number(3), class_code varchar2(3), class_num number(4)); 
insert into class values (1, 'CS', 999); 
insert into class values (1, 'MA', 111); 
insert into class values (1, 'DE', 222); 
insert into class values (2, 'CS', 999); 
insert into class values (2, 'MA', 111); 
insert into class values (2, 'DE', 222); 
insert into class values (3, 'CS', 999); 
insert into class values (4, 'CS', 999); 

выход:

ID NAME 
---- ----------- 
    2 John Doe 
+0

Если я изменю один класс, порученный Джоном Доу, который означает, что он больше не соответствует точно всем классам, указанным Foo Bar, я все равно получаю John Doe, он должен возвращать пустую строку. – hello

0

Что об этом:

SELECT * 
    FROM instructor i 
WHERE NOT EXISTS 
      (SELECT * 
      FROM class c 
      WHERE c.instructor_id = i.human_id 
      MINUS 
      SELECT * 
      FROM class c 
      WHERE instructor_id = (SELECT human.id 
            FROM human 
            WHERE FIRST = 'Foo' AND LAST = 'Bar')); 
-1

Я предположил, инструктор может научить тот же класс более одного раза (если они не могут запроса можно несколько упростить). Я также предположил, что ввод задается как «имя, фамилия», а не непосредственно man.id, хотя это плохой способ запуска запросов, и что, если более одного инструктора имеют одно и то же имя и фамилию? использовать уникальные идентификаторы

во всяком случае, здесь может быть изменен, чтобы учесть изменения в модели данных или модели ввода,... сейчас она основана на требованиях Op как указано

with sel(p_id) as (select id from human where first = 'foo' and last = 'bar'), 
    a(i, ct) as (select instructor_id, count(distinct class_code || class_num) 
        from class group by instructor_id) 
select i from a join sel on i != p_id 
where 
(select count(distinct class_code || class_num) from class 
         where instructor_id in (p_id, i)) = 
(select min(ct) from a a1 where a1.i in (p_id, a.i)); 
+0

Никогда не слышал назад - это делает то, что вам нужно? – mathguy

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