Предикат различимости

Функция

Определение предиката различимости двух записей.

Спецификация
     
<​тип проверки​>::=
{ IS [ NOT ] DISTINCT FROM }
<​проверяемая запись​>::=
<​сличаемая запись​>::=
Синтаксические правила
  1. <​Проверяемая запись​> и <​сличаемая запись​> должны быть одинаковой степени и иметь совместимые типы данных.

    select model
      from auto
     where (1, 2, 3) is not distinct from (0+1,4-2,sqrt(9)) limit 2;
    |MERCURY COMET GT V8 |
    |A-310               |
Общие правила
  1. <​Проверяемая запись​> с именами столбцов c1,c2,...,cn и <​сличаемая запись​> с именами столбцов d1,d2,...,dn считаются записями-дубликатами, если для каждого i (i=1,2,...,n):

    • ci и di не содержат NULL-значения, а их реальные значения равны;

    • ci и di содержат NULL-значения.

    create or replace table auto_old (make char(20), color char(10));
    insert into auto_old(make, color) values ('FORD', 'RED');
    insert into auto_old(make, color) values ('FORD', 'GREEN');
    
    select count(model) from auto as a, auto_old as o
     where (a.make,a.color) is not distinct from (o.make, o.color);
    |         10|
    create or replace table auto_old (personid int, make char(20), color char(10));
    insert into auto_old(personid, make, color) values (1, 'FORD', 'RED');
    insert into auto_old(personid, make, color) values (134, 'FORD', 'GREEN');
    
    select count(model)
      from auto as a, auto_old as o
     where (a.make, a.color) is distinct from (o.make, o.color)
       and a.personid=o.personid;
    |          2|
  2. Предикат возвращает значение TRUE в том и только в том случае, когда <​проверяемая запись​> и <​сличаемая запись​> не являются дубликатами. В противном случае значением предиката является FALSE.

  3. Если предикат DISTINCT содержит модификатор NOT, то предикат (<​проверяемая запись​>) IS NOT DISTINCT FROM (<​сличаемая запись​>) эквивалентен NOT (<​проверяемая запись​>) IS DISTINCT FROM (<​сличаемая запись​>).

    Эти конструкции эквивалентны:

    select count(model) from auto
     where (make,color) is not distinct from values('FORD', 'RED');
    select count(model) from auto
     where not (make,color) is distinct from values('FORD', 'RED');
    |          5|
Пример

Найти отделы, руководители которых не являются тёзками Петрова Петра.

create or replace table dept(dept_no int, boss_surname char(10), boss_name char(10));
insert into dept values (1,'ИВАНОВ','ИВАН');
insert into dept values (2,'ПЕТРОВ',NULL);
insert into dept values (3, NULL, NULL);
insert into dept values (4,'ПУПКИН','ВАСИЛИЙ');
insert into dept values (5,'ПЕТРОВ','ПЕТР');
insert into dept values (6, NULL, NULL);

Результаты нижеследующих запросов идентичны:

select dept_no
  from dept
 where ('ПЕТРОВ','ПЕТР') is distinct
  from (boss_surname,boss_name);

select dept_no
  from dept
 where (boss_surname, boss_name) is distinct from
 (select boss_surname, boss_name
    from dept
   where boss_surname='ПЕТРОВ'
     and boss_name='ПЕТР');
 -------
|          1|
|          2|
|          3|
|          4|
|          6|