<<На Главную     <В  Советы по MS SQL Server

  Задача сравнения двух списков является, пожалуй, одним из стандартных положений, которое  должен уметь грамотно отрабатывать всякий мало-мальски сведущий специалист по базам данных. Несмотря на то, что здесь, в общем-то, нет ничего сложного, отсутствие наглядных, простых и не слишком громоздких примеров и описаний, явно не содействует тому, чтобы пользователи смогли четко разобраться во всех этих LEFT/RIGHT/INNER JOIN' ах. Сейчас попробуем восполнить этот пробел на чрезвычайно простой базе данных.

 

 

 

  Итак, предположим, что у некой торговой фирмы бытовой техники есть два магазина . Один (крупный) торгует всем подряд , а другой небольшой филиал исключительно компьютерной техникой. Соответственно, имеютcя два справочника товаров. Один , как бы это сказать, глобальный, и будет называться tovary. А другой  локальный - computers :

 

Обратите внимание, товары Сканер, Принтер, Компьютер, Планшет, Копир и Клавиатура присутствуют в обоих списках, а Мышь и Монитор есть только в справочнике Computers

Прим. Материалы этого учебного примера можно скачать по сл. ссылке : https://yadi.sk/d/ljRC3fVvcjZsC

В распакованном виде  выглядит так:

Как смонтировать базу - можно посмотреть в этой статье

Как выполнить запрос - смотрите тут

Начнем, пожалуй, с объединения inner joinкоторое выводит список товаров, которые присутствуют в обоих справочниках (запрос InnerJoin1 в нашем учебном примере):

Select * from computers c

inner join tovary t on c.tovar = t.tovar

Прим. Соединять две таблички этого условного примера будем для наглядности по столбцам наименования Tovar, которые для нашего случая имеют одинаковое название. Строго говоря, оно может быть абсолютно любым. Такие поля, по которым происходит соединение табличек иногда называют 'ключевыми'. Вообще говоря, соединять таблички по символьным полям (тем более если символы не цифры!) не лучшая идея.

Присоединение inner join имеет одну особенность - оно не меняет количество строк в выборке, даже если поменять таблички в запросе местами (запрос InnerJoin2 в учебном примере):

Так, переходим к left join . Соответствующий запрос на объединение для нашего простенького примера ( LeftJoin в учебной базе) ...

Select * from computers c

left join tovary t on c.tovar = t.tovar

 

... выводит такой список:

 

 

 

Обратите внимание, запрос left join присоединил  товары, которых нет в списке computersи пометил эти отсутствующие записи в 'глобальном' (условно назовём его так) списке как null.  Этот момент поможет решить задачку выборки компьютерных товаров, которых нет в большом списке. Текст запроса  будет такой (LeftJoinIsNull в учебной базе):

 

Select * from computers c

left join tovary t on c.tovar = t.tovar

where t.Tovar is null

 

 

А используя функцию агрегирования Count() в следующем запросе ( SelCount в примерах):

 

Select COUNT(*) as Kolvo from computers c

left join tovary t on c.tovar = t.tovar

where t.Tovar is null

 

... можно подсчитать количество таких отсутствующих товаров:

 

 

Однако, вернемся к рассмотрению операции left join. Если поменять местами таблички в запросе left join, вроде этого (запрос LeftJoin2 в учебной базе):

 

Select * from tovary t

left join computers c on c.tovar = t.tovar

 

 ... то получим немного иную выборку:

 

 

Следующий запрос right join  присоединяет справа к табличке computers  список товаров, даже если они отсутствуют в исходной табличке  (запрос RightJoin в учебной базе):

Select * from computers c

right join tovary t on c.tovar = t.tovar

Кстати сказать, такой немного модифицированный запрос поможет сравнить два списка на предмет  поиска расхождений( чтобы показать те записи (товары) из 'глобального' справочника, что отсутствуют в локальном).  Далее следует пример такого запроса (запрос RightJoinIsNull в учебной базе):

Select t.id , t.Tovar from computers c

right join tovary t on c.tovar = t.tovar

where c.Tovar is null

А при использовании операции соединения  full join получите список всех товаров (запрос FullJoin в учебной базе):

Select * from computers c

full join tovary t on c.tovar = t.tovar

Всем успехов при изучениии t-sql !

Simashkov.2014

26.10.2014 г.

Назад