суббота, 13 марта 2010 г.

Недокументированный синтаксис оператора проверки совпадений

Оператор В(IN) - проверки совпадений, позволяет проверить, совпадает ли значение выражения, указанного справа от него, с одним из значений, описанных слева. Если совпадает хотя бы с одним – результатом оператора будет ИСТИНА, иначе – ЛОЖЬ. Применение НЕ изменяет действие оператора на обратное.

В документация описаны 3! способа применения оператора В(IN):
  1. <Выражение> [НЕ] В  ( <Список значений> | <Массив значений> )
  2. <Выражение> [НЕ] В ИЕРАРХИИ  ( <Выражение> | <Список значений> | <Массив значений> )
  3. <Выражение> [НЕ] В [ИЕРАРХИИ] ( <Описание запроса> )

однако есть и четвертый

  1. (<Выражение>[, <Выражение> [, …]]) [НЕ] В  ( <Описание запроса> )
Оператор проверят совпадение для каждого выражения(операнда) описанного слева, с соответствующим полем запроса описанного справа.  Количество операндов слева должно соответствовать количеству полей запроса справа.

Пример:

//Поиск дублей элементов справочника по набору полей
ВЫБРАТЬ
    Номенклатура.Ссылка
ИЗ
    Справочник.Номенклатура КАК Номенклатура
    ГДЕ (Ссылка.Код,Ссылка.Наименование,1) НЕ В (ВЫБРАТЬ
                                                                                                           Номенклатура.Код,
                                                                                                           Номенклатура.Наименование,
                                                                СУММА(1) КАК Флаг
                                                             ИЗ
                                                    Справочник.Номенклатура КАК Номенклатура
                                                
                                                 СГРУППИРОВАТЬ ПО
                                                    Номенклатура.Наименование,
                                                    Номенклатура.Код)
Хочется еще отметить что данная конструкция поддерживается SQL, однако в документации например по MSSQL явно указано, " ....Вложенный запрос с результирующим набором из одного столбца.".  Вот транслируемый запрос к СУБД(MSSQL)
SELECT
        Q_000_T_001.ID
FROM
        Reference95 Q_000_T_001
        WHERE
        (NOT((  CAST(Q_000_T_001.ID AS REF(Reference95)).Code,
                CAST(Q_000_T_001.ID AS REF(Reference95)).Description,
                1) IN ( SELECT
                                Q_001_T_001.Code Q_001_F_000,
                                Q_001_T_001.Description Q_001_F_001,
                                SUM(1) Q_001_F_002
                        FROM
                                Reference95 Q_001_T_001
                        GROUP BY
                                Q_001_T_001.Description,
                                Q_001_T_001.Code
                        )
                ))
Выдержка из документации по 1С:Предприятие 8.1

Форма оператора В для проверки совпадения с одним из перечисленных

Примером применения данного оператора может послужить следующее:

Пример:

Выбрать
   Справочник.Номенклатура.Наименование
Где
   Справочник.Номенклатура.Родитель.Наименование
   В ("Бытовая техника", "Оргтехника")

Форма оператора В для проверки принадлежности по иерархии

Для справочников проверка может осуществляться и на принадлежность по иерархии. Результатом оператора В ИЕРАРХИИ будет ИСТИНА, если значение выражения слева является ссылкой на элемент справочника и входит во множество значений справа или иерархически принадлежит какой-нибудь группе, содержащейся в этом множестве:

Пример:

// В качестве параметра Группа в запрос передается ссылка
// на какую-либо группу справочника Номенклатура.
Выбрать
   Справочник.Номенклатура.Наименование
Где
   Справочник.Номенклатура.Ссылка В ИЕРАРХИИ (&Группа)
В качестве множества значений, на совпадение с которыми выполняется проверка, может фигурировать и результат запроса. В этом случае справа от оператора В необходимо указать описание запроса.

Пример:

Выбрать
   Справочник.Номенклатура.Наименование
Где
   Справочник.Номенклатура.Ссылка В ИЕРАРХИИ
   (
      ВЫБРАТЬ
         Справочник.Номенклатура.Ссылка
      ГДЕ
         Справочник.Номенклатура.Наименование = "Одежда"
   )

Форма оператора В для проверки совпадения значения с одним из результата запроса

Примером применения данного оператора может послужить следующее:

Пример:

// Выбрать названия товаров, которые присутствовали в расходных накладных
ВЫБРАТЬ
   Товары.Наименование
ИЗ
   Справочник.Товары КАК Товары
ГДЕ
   Товары.Ссылка В
     (
      ВЫБРАТЬ
         РасхНаклСостав.Товар
      ИЗ
         Документ.РасхНакл.Состав КАК РасхНаклСостав
     )

Результат запроса:

Товары
Кран
Вантус
Стол
Стул
Для получения противоположного результата, то есть, если нужно определить, что значение не совпадает ни с одним из результата запроса, запрос выглядит следующим образом:

Пример:

// Выбрать названия товаров, которые присутствовали в расходных накладных
ВЫБРАТЬ
   Товары.Наименование
ИЗ
   Справочник.Товары КАК Товары
ГДЕ
   Товары.Ссылка НЕ В
     (
      ВЫБРАТЬ
         РасхНаклСостав.Товар
      ИЗ
         Документ.РасхНакл.Состав КАК РасхНаклСостав
     )

Результат запроса:

Товары
Сантехника
Мебель
Заметим, что из запроса операции В возможно обращение к полям таблиц, которые встречались во внешнем запросе до появления операции.

Пример:

// Выбрать названия товаров, которые присутствовали в расходных накладных
ВЫБРАТЬ
   Товары.Наименование
ИЗ
   Справочник.Товары КАК Товары
ГДЕ
   Товары.Ссылка В
     (
      ВЫБРАТЬ
         РасхНаклСостав.Товар
      ИЗ
         Документ.РасхНакл.Состав КАК РасхНаклСостав
      ГДЕ
         РасхНаклСостав.Товар = Товары.Ссылка
     )

Результат запроса:

Товары
Кран
Вантус
Стол
Стул