Имя: Пароль:
1C
1С v8
Условия на таблицы при полном соединении
0 Feunoir
 
07.05.13
10:35
Всю жизнь считал, что если нужно наложить условия на таблицы до соединения, то достаточно вписать эти самые условия в раздел "ПО". Поэтому и написал простой и естественный запрос:


ВЫБРАТЬ РАЗРЕШЕННЫЕ
   ЭтапыОбъектовСтроительства.Этап,
   ЭтапыОбъектовСтроительства.Ссылка,
   НоменклатурныеГруппы.гт_ЭтапРабот,
   НоменклатурныеГруппы.гт_ОбъектСтроительства
ИЗ
   Справочник.ОбъектыСтроительства.гт_Этапы КАК ЭтапыОбъектовСтроительства
       ПОЛНОЕ СОЕДИНЕНИЕ Справочник.НоменклатурныеГруппы КАК НоменклатурныеГруппы
       ПО ЭтапыОбъектовСтроительства.Этап = НоменклатурныеГруппы.гт_ЭтапРабот
           И (НоменклатурныеГруппы.гт_ОбъектСтроительства = &Ссылка)
           И (ЭтапыОбъектовСтроительства.Ссылка = &Ссылка)


В результате получил две с половиной тысячи строк вместо ожидаемых шести. Пришлось городить монстра с предварительной фильтрацией исходных таблиц во вложенных запросах и слиянию уже фильтрованных данных.

Это я чего то не то делаю, или вариантов всё-таки нет?
1 МихаилМ
 
07.05.13
10:37
есть ещё
раздел WHERE (ГДЕ)
2 Wobland
 
07.05.13
10:37
полное соединение такое полное
3 Широкий
 
07.05.13
10:37
ВНУТРЕННЕЕ СОЕДИНЕНИЕ
4 Ненавижу 1С
 
гуру
07.05.13
10:39
ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.НоменклатурныеГруппы КАК НоменклатурныеГруппы
       ПО ЭтапыОбъектовСтроительства.Этап = НоменклатурныеГруппы.гт_ЭтапРабот
           И НоменклатурныеГруппы.гт_ОбъектСтроительства=ЭтапыОбъектовСтроительства.Ссылка
ГДЕ ЭтапыОбъектовСтроительства.Ссылка = &Ссылка
5 RomaH
 
naïve
07.05.13
10:43
(0) похоже зря ты так считал
соединение по условию

полное соединение - это ВЯС таблица слева  ВСЯ таблица справа
но так как соединение - то эти таблицы будут "накладываться" по условию указаному в "ПО"
?
6 Feunoir
 
07.05.13
11:47
Коллеги, я знаю чем отличается полное соединение от правого, левого и внутреннего. Уже лет 15, наверное. Поэтому не советуйте, пожалуйста, внутреннее соединение, когда мне нужно внешнее.

(5) Дело в том, что для, например, левого соединения это работает. Если в ПО написать условие для соединяемой таблицы, то она отфильтруется по условию и свяжется.
7 RomaH
 
naïve
07.05.13
11:58
(6) ага
  ВЫБРАТЬ
   ФизическиеЛица.Ссылка,
   РаботникиОрганизацийСрезПоследних.Должность
ИЗ
   Справочник.ФизическиеЛица КАК ФизическиеЛица
       ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.РаботникиОрганизаций.СрезПоследних КАК РаботникиОрганизацийСрезПоследних
       ПО ФизическиеЛица.Ссылка = РаботникиОрганизацийСрезПоследних.Сотрудник.Физлицо
       И  ФизическиеЛица.Ссылка = &Ссылка
8 User_Agronom
 
07.05.13
12:02
(6) <Если в ПО написать условие для соединяемой таблицы, то она отфильтруется по условию и свяжется>
Что-то мне не верится. Может в каких-то частных случаях да, а в общем совсем нет
9 patapum
 
07.05.13
12:12
(6) тот, кто это знает (уже лет 15), не задает таких вопросов
10 kosts
 
07.05.13
12:26
(0) > если нужно наложить условия на таблицы до соединения, то достаточно вписать эти самые условия в раздел "ПО"

Это условие соединения, а не условие фильтрации. Строки левой и правой таблицы по любому все будут выведены. Другое дело как они будут соединены.

(6) > Дело в том, что для, например, левого соединения это работает. Если в ПО написать условие для соединяемой таблицы, то она отфильтруется по условию и свяжется.

Опять же смотря для какой таблицы, левой или правой.
11 User_Agronom
 
07.05.13
13:04
ВЫБРАТЬ
  Таб1.Поле1,
  Таб1.Поле2,
  Таб2.Поле3,
  Таб2.Поле4
ИЗ
  Таблица1 КАК Таб1
ЛЕВОЕ СОЕДИНЕНИЕ
  Таблица2 КАК Таб2
ПО
  Таб1.Поле1=Таб2.Поле1
  И
  Таб1.Поле2=Таб2.Поле2

В результате вполне может быть строка:
<знач> <знач> <null> <null>

В этом случае будут выведены все строки первой таблицы и никаким условием в разделе ПО их отфильтровать нельзя.
Удивительно, конечно, что за 15 лет написания запросов сиё не установлено.
12 Feunoir
 
07.05.13
13:04
(9) Соединения (join'ы) вообще и конкретная их реализация в 1С несколько разные вещи. Interbase с Firebird'ом накладывали условия на исходную таблицу ориентируясь на раздел ГДЕ. И поэтому там вообще таких плясок не было.

(8), (10)


ВЫБРАТЬ
   "а" КАК Номенклатура,
   1 КАК Остаток
ПОМЕСТИТЬ Остатки

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
   "б",
   2
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
   "а" КАК Номенклатура,
   4 КАК Оборот
ПОМЕСТИТЬ Обороты

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
   "б",
   2
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
   Остатки.Номенклатура КАК НомОстаток,
   Обороты.Номенклатура КАК НомОборот,
   Обороты.Оборот,
   Остатки.Остаток
ИЗ
   Остатки КАК Остатки
       ЛЕВОЕ СОЕДИНЕНИЕ Обороты КАК Обороты
       ПО Остатки.Номенклатура = Обороты.Номенклатура
           И (Обороты.Номенклатура = &Номенклатура)



Задайте параметр Номенклатура = "б", и попробуйте выполнить запрос. А потом закомментируйте "И (Обороты.Номенклатура = &Номенклатура)". А потом перенесите это в ГДЕ. Получится три разных результата.
13 Feunoir
 
07.05.13
13:10
(11) Ты внутренний механизм соединения знаешь? Что и в каком порядке ограничивается и связывается? Если знаешь, просвети плз.
14 mkanaev
 
07.05.13
13:15
(12) с чего это ониразные, и там и там в конструкции on идёт описание условий соединения полей, однако это не ограничивает записи, в полном тебе нужно where, как говорят многие програмеры 1С перевели sql промтом
15 kosts
 
07.05.13
13:15
(12) >Получится три разных результата.  
Думаю так и должно быть.
16 Feunoir
 
07.05.13
13:15
(10) >Это условие соединения, а не условие фильтрации.

Вот это и хреново, что нельзя отфильтровать таблицу, а потом соединить по отфильтрованному. Приходится монстров городить либо через временную таблицу, либо через вложенный запрос.
17 Feunoir
 
07.05.13
13:17
(14) если я наложу условия в where (ГДЕ), то придется либо добавлять условия на "ИЛИ ... ЕСТЬ NULL", либо получу аналог внутреннего соединения.
18 mkanaev
 
07.05.13
13:18
(17) не внутреннего а левого!
19 mkanaev
 
07.05.13
13:19
если два параметра ограничишь то внутреннего
20 Feunoir
 
07.05.13
13:20
(19) да, я про запрос из первого поста
21 User_Agronom
 
07.05.13
13:20
(12) Нужно поменять две строки в этом запросе
Должно быть так:

ВЫБРАТЬ
   Остатки.Номенклатура КАК НомОстаток,
   Остатки.Остаток,
   Обороты.Номенклатура КАК НомОборот,
   Обороты.Оборот


Ничего не изменилось, но стало гораздо наглядней.

Тогда от всех манипуляций будет понятно, что при первых двух полностью! выводилась первая таблица (+присоединённые строки из второй) и только перенос условия в раздел ГДЕ помог уменьшить число записей.
Таким образом, при левом соединении изменяя условие в ПО уменьшить количество записей не получиться))
22 mkanaev
 
07.05.13
13:25
(20) ну только через where (tab1.pole1 = :Znachenie1 or tab1.pole1 is null) and (tab2.pole1 = :Znachenie2 or tab2.pole1 is null)

Подругому никак, да и в Firebird так же... единая логика выполнения запросов...
23 Feunoir
 
07.05.13
13:33
(21) Правильно. Именно это я и хотел выяснить в своём первом посте. Полезные мысли были в (10) и в (21) окончательное подтверждение. Остальное вода и брызги.

(22) К сожалению в моём случае оно выводит ещё и записи в которых оба поля NULL. Потому что есть исходные записи, в которых поля не заполнены.

Зато в процессе у меня родился ещё один вариант. Который в моём частном случае работает и выглядит менее громоздким, чем со вложенными запросами.

Впрочем ладно, всё понятно, всем спасибо.
2 + 2 = 3.9999999999999999999999999999999...