Вариант 1.
Как сказано в комментариях, колонка деда не нужна. Отношение родитель - дед - это то же самое отношение, что и ребенок - родитель.
Как:
select a.child, a.parent, b.parent
from parentchild a
, parentchild b
where b.child = a.parent
Вариант 2.
Если, однако, вы настаиваете на использовании этого макета таблицы, вы можете определить триггер до вставки или обновления таблицы, который проверяет, есть ли уже запись в таблице с таким же родителем, но другой дедушка. Если такая строка найдена, триггер должен выйти из строя и пометить ошибку, иначе запись может быть вставлена или обновлена.
Пример кода для триггера:
create trigger parentchild_iu
before insert or update
on parentchild for each row
declare
v_count number;
begin
select count(*) into v_count
from parentchild p
where p.parent = :new.parent
and p.grandparent != :new.grandparent;
if v_count != 0 then
raise_application_error("Parent/Grandparent combination invalid.");
end if;
end;
Вариант 3.
И, как третий вариант, вы можете разделить таблицу на две таблицы: childparent и parentgranparent и получить следующий запрос:
select a.child, a.parent, b.grandparent
from childparent a
, parentgrandparent b
where a.parent = b.parent;
И в обеих таблицах определяют уникальные ключи для обоих столбцов.