Правильная ссылка на эту страницу
http://az-design.ru/Support/DataBase/SQL/SQL0001.shtml

SQL-рецепт – как найти того, кого нет

       Часто встречающаяся задача – найти записи, которые есть в таблице А и отсутствуют в таблице Б. Или не сами записи, а значения некоторых полей, которые должны быть в обоих таблицах, но по каким-то причинам в одной из них отсутствуют. Так случилось при разработке БД по определению стоимости АМТС и их ремонта. В нормативах по ремонту обнаружились детали, которые отсутствовали в каталогах запчастей (ВАЗ).
       Для поиска таких расхождений и был разработан этот запрос.
       Структура таблицы, в которой есть ВСЕ детали, назовем ее внешней out, приведена ниже:

Create table VAZTO210815
      (VZTOID        Integer not null Primary key,
       VZTOGroup     AZNOTXT references VAZTOGroup on update cascade,
       VZNoPos       Integer,
       VZKodDetal    Integer,
       VZKodRabot    Integer,
       VZDetalName   AZTitle,
       VZ21083       DECIMAL(8,2),  KVZ21083   Integer default 1,
       VZ21083i      DECIMAL(8,2),  KVZ21083i  Integer default 1,
       VZ21150       DECIMAL(8,2),  KVZ21150   Integer default 1,
       VZ21150i      DECIMAL(8,2),  KVZ21150i  Integer default 1);
Commit;

       Структура таблицы, в которой отсутствуют некоторые детали, назовем ее внутренней inp, приведена ниже:

Create table VAZDetal
      (VAZDIR        AZNOTXT NOT NULL,
       VAZKOD        Integer default 0 Not null,
       VAZKODA       Integer default 0 Not null,
       VAZNum        AZNOTXT,
       VAZINDX       AZNOTXT,
       VAZName       AZTitle,
       VAZDCnt       Integer default 0,
       VPrefCode     AZNoTXT,
       VBaseCode     AZNoTXT,
       VSufxCode     AZNoTXT,
       VIBasCode     Integer,
Primary Key (VAZDIR,VAZKOD,VAZKODA));
Commit;

       Запрос, который реализует поставленную задачу, приведен ниже:


Select distinct VZKodDetal,VZDetalName from VAZTO210815 
   where VZKodDetal in (Select distinct VZKodDetal from VAZTO210815 out
   where VZKodDetal not in (Select VIBasCode from VAZDETAL inp
   where out.VZKodDetal=inp.VIBasCode));

       Запрос действует следующим образом:

       1) Внутренний запрос (синий) –

Select VIBasCode from VAZDETAL inp where out.VZKodDetal=inp.VIBasCode

       выбирает из таблицы VAZDetal те записи, коды деталей которых есть в таблице VAZTO210815.

       2) Второй запрос (зеленый) –

Select distinct VZKodDetal from VAZTO210815 out where VZKodDetal not in

       выбирает из таблицы VAZTO210815 уникальные записи, коды деталей которых отсутствуют в предыдущем запросе (not in).

       3) И, наконец, последний запрос (красный) формирует вывод не только кодов деталей, но и их наименований для тех кодов, которые выдал предыдущий запрос.

       Если, кто-нибудь найдет более красивое или эффективное решение, просьба напишите.

© 10.04.2005, Архангельский А.Г.

Оглавление
Главная страница




Дата последнего изменения:
Thursday, 21-Aug-2014 09:10:44 MSK


Постоянный адрес статьи:
http://az-design.ru/Support/DataBase/SQL/SQL0001.shtml