Переключение на Главную Страницу Страницы: 1 ОтправитьПечать
Обычная тема Двойной LEFT JOIN - размышления (число прочтений - 5112 )
lustin
1c++ power user
Отсутствует


1C *.*, ROR, Java - на
этом остановимся

Сообщений: 907
Местоположение: Москва
Зарегистрирован: 20. Октября 2006
Пол: Мужской
Двойной LEFT JOIN - размышления
20. Февраля 2007 :: 11:02
Печать  
преамбула:
- как уже известно некоторым многоуважаемым участникам я сейчас занимаюсь преобразованием одного отчета (ускорением работы, оптимизацией, рефакторингом как угодно).
- отчет состоял раньше из нескольких простых прямых запросов и алгоритма обработки итоговой таблицы
- теперь я пытаюсь все прямые запросы объединить в один большой оптимизированный запрос...
- быстро объединить не получилось, поэтому все запросы были разделены на простейшие с целью анализа возможности объединения (оптимизации)
в запросах так или иначе используются 6 регистров и небольшая куча Улыбка справочников....

РАЗМЫШЛЕНИЯ:
1. Первое что я сделал открыл ссылки
- http://metaprog.co.ua/secrprog/opisanietabl.html - описание таблиц
- активно просмотрел DD файл
- еще раз перечитал FAQ по прямым запросам
- открыл в постоянном режиме http://metaprog.co.ua/secrprog/tran_sql.html#_1
- прочитал все что было на intuit.ru по T-SQL

2. Решил начать с простого:
- получить таблицу формата
| ТоварПопавшийВИтогиРегистра | ТипЦеныВЫбранныйПользователем | ЗначениеЦеныНаЗаданнуюДату |

И вот здесь произошел затык ровно на сутки (по состоянию на сегодняшний день)

Вроде понятно что алгоритм должен быть

А)
SELECT
Регистр.Товар as Товар
СправочникЦена as ТипЦены
Периодический.Цена as Число
FROM
Регистр
LEFT OUTER JOIN Справочник.Цены ON Регистр.Товар = Справочник.Цены.Владелец
LEFT OUTER JOIN Периодический ON Справочник.Цены.id = Периодический.objid and (???)

но вместо ??? необходимо вставить условия связи с таблицей товаров из регистра
по логике на самом деле Регистр.Товар <-> Периодический.objid.Владелец - то есть ссылка то существует но не для SQL запроса...

Б) Считаем что по определению ошибаюсь где-то Я САМ!!! поэтому лезем в FAQ по прямым запросам видим на странице 20 следующую конструкцию для поиска периодических реквизитов

======================================
|SELECT  
|      СпрН.Descr AS Наименование,
|      Цены.Цена as [Цена $Число]
|FROM
|      $Справочник.Номенклатура СпрН
|LEFT JOIN
|      $Справочник.Цены СпрЦ ON СпрЦ.ParentExt = СпрН.ID AND
|                           $СпрЦ.ТипЦен = :ТипЦен";
|LEFT JOIN (
|      SELECT
|            Период.objid as objid,
|            Период.value as Цена
|      FROM 1sconst as Период
|      WHERE
|            Период.date IN
|            (SELECT
|                  MAX(Константа.date)
|            FROM 1sconst as Константа
|            WHERE
|                  (Константа.date <= :ВыбДата ~~)
|                  AND (Константа.id = $ИсторияРеквизита.Цены.Цена)
|                  AND (Константа.objid = Период.objid)
|            )
|            AND Период.id = $ИсторияРеквизита.Цены.Цена
|      ) as Цены ON Цены.objid = СпрЦ.id

=====================================

Попробуем скопировать подобную конструкцию в тестовый запрос

После установки текстовых параметров :ТипЦен и :ВыбДата
мы для начала получим синтаксическую ошибку из-за кавычки после :ТипЦен

А затем FAILED! ICommandText::Execute(): SQL: Column '     ' is not found.

Пытаясь выяснить в чем проблема, не забывая что по определению Я ИЗНАЧАЛЬНО ошибаюсь - читаем описание команды LEFT (OUTER) JOIN, и получается что:
"Для каждого последеющего JOIN необходимо задавать соответствие со всеми предыдущими таблицами" то есть возвращаемся к ???

LEFT OUTER JOIN Периодический ON Справочник.Цены.id = Периодический.objid and (???)

Что из всего вышесказанного следует кроме того что FAQ получается Неверный Озадачен слегка.

Возникает вопрос:
- кто-нибудь сталкивался с ДВОЙНЫМИ LEFT JOIN подобного вида для ДБФ баз?
- to Славко: все таки поле objid в таблице 1SCONST это ссылка на объект владелец
Периодического реквизита а id - идентификатор реквизита
То есть 1SCONST.objid as [objid $Справочник.Цены]

P/S Просьба откликнуться тех у кого ДБФ база и структура хранения цен товаров

Справочник.Номенклатура ->подчиненый справочник-> Справочник.Цены - реквизит Справочник.Цены.Цена (Периодический)

P/S/S - публикую в курилке развернутое описание проблемы в целях:
А) если все таки Я ЧТО ТО упустил, тему можно было бы удалить, чтобы не позорится
Б) обозначить свое желание никого не отвлекать от работы

  

бизнес-процесс как техническое задание прекрасно, только у бизнеса нет процессов; у бизнеса есть желание выжить
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
spock
1c++ developer
1c++ moderator
Отсутствует



Сообщений: 822
Местоположение: Новосибирск
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Двойной LEFT JOIN - размышления
Ответ #1 - 20. Февраля 2007 :: 11:56
Печать  
Можно печататься в юмористических журналах, смешно получается Улыбка

Может поможет делу (Справочник НормыРасходов подчинен справочнику Номенклатура. Периодические реквизиты: Справочник.НормыРасходов.Норма (сколько по норме), Справочник.НормыРасходов..КолПрод (на какое количество продукции), Справочник.НормыРасходов.Стоимость (стоимость по норме)):

Код
Выбрать все
	|SELECT
	|	сНормы.id as [ЭлНорм $Справочник.НормыРасходов],
	|	$сНормы.ВидЭлемента as [ВидЭлемента $Перечисление.ВидыНоменклатуры],
	|	$сНормы.Элемент as [Элемент $Справочник.Номенклатура],
	|	сНорма.value as [Норма $Число],
	|	сКолВо.value as [КолПрод $Число],
	|	сСтоим.value as [Стоимость $Число]
	|
	|FROM
	|	$Справочник.НормыРасходов as сНормы
	|
	|LEFT JOIN $Справочник.Номенклатура as Ном ON (Ном.id = сНормы.parentext) AND (Ном.id = :ТекНоменк)
	|
	|LEFT JOIN (
	|		SELECT
	|			c_dt.objid as objid,
	|			c_dt.value as value
	|		FROM 1sconst as c_dt
	|		WHERE
	|			c_dt.date IN (SELECT MAX(c.date)
	|						FROM 1sconst as c
	|						WHERE
	|							(c.date <= :КонДата~~) AND
	|							(c.id = $ИсторияРеквизита.НормыРасходов.Норма)
	|							AND (c.objid = c_dt.objid)
	|						) AND
	|			c_dt.id = $ИсторияРеквизита.НормыРасходов.Норма
	|		) as сНорма
	|ON сНорма.objid = сНормы.id
	|
	|LEFT JOIN (
	|		SELECT
	|			c_dt.objid as objid,
	|			c_dt.value as value
	|		FROM 1sconst as c_dt
	|		WHERE
	|			c_dt.date IN (SELECT MAX(c.date)
	|						FROM 1sconst as c
	|						WHERE
	|							(c.date <= :КонДата~~) AND
	|							(c.id = $ИсторияРеквизита.НормыРасходов.КолПрод)
	|							AND (c.objid = c_dt.objid)
	|						) AND
	|			c_dt.id = $ИсторияРеквизита.НормыРасходов.КолПрод
	|		) as сКолВо
	|ON сКолВо.objid = сНормы.id
	|
	|LEFT JOIN (
	|		SELECT
	|			c_dt.objid as objid,
	|			c_dt.value as value
	|		FROM 1sconst as c_dt
	|		WHERE
	|			c_dt.date IN (SELECT MAX(c.date)
	|						FROM 1sconst as c
	|						WHERE
	|							(c.date <= :КонДата~~) AND
	|							(c.id = $ИсторияРеквизита.НормыРасходов.Стоимость)
	|							AND (c.objid = c_dt.objid)
	|						) AND
	|			c_dt.id = $ИсторияРеквизита.НормыРасходов.Стоимость
	|		) as сСтоим
	|ON сСтоим.objid = сНормы.id
	|
	|WHERE
	|	сНормы.PARENTEXT = :ТекНоменк
 

  
Наверх
ICQ  
IP записан
 
lustin
1c++ power user
Отсутствует


1C *.*, ROR, Java - на
этом остановимся

Сообщений: 907
Местоположение: Москва
Зарегистрирован: 20. Октября 2006
Пол: Мужской
Re: Двойной LEFT JOIN - размышления
Ответ #2 - 20. Февраля 2007 :: 12:17
Печать  
Не, смешить я никого не хотел.... Круглые глаза

Вообщем  Подмигивание помогло - а конкретно вопрос в синтаксисе почему-то

А менять то надо было первый ON - проблема решается заведением условий ON в скобки...

Так что:

1. FAQ надо править... Неужели этот тестовый пример работает у автора...

2. to spock - респект и уважуха, МНЕ - позор и ПЕПЕЛ на голову.

ВОТ!!!


  

бизнес-процесс как техническое задание прекрасно, только у бизнеса нет процессов; у бизнеса есть желание выжить
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
spock
1c++ developer
1c++ moderator
Отсутствует



Сообщений: 822
Местоположение: Новосибирск
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Двойной LEFT JOIN - размышления
Ответ #3 - 20. Февраля 2007 :: 13:43
Печать  
Цитата:
МНЕ - позор и ПЕПЕЛ на голову

Крайне самокритично, имхо Улыбка
  
Наверх
ICQ  
IP записан
 
trdm
1c++ power user
qt1l developer
1c++ moderator
Отсутствует



Сообщений: 2343
Местоположение: г. Ростов-на-Дону
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Двойной LEFT JOIN - размышления
Ответ #4 - 20. Февраля 2007 :: 15:50
Печать  
Забудь про пепел, фигня это все.
это называется отсутствие опыта.
Такие вещи нарабатываются только опытом.
(спасибо Авторам 1С++ за прямые запросы, а тобы так и сидел лопух-лопухом)
И вложенные селекты снача вообще не постижимы разумом, к этому надо приваыкнуть....
  
Наверх
IP записан
 
Arta
1c++ power user
Отсутствует



Сообщений: 2537
Местоположение: Нижний Новгород
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Двойной LEFT JOIN - размышления
Ответ #5 - 20. Февраля 2007 :: 17:12
Печать  
+1 Улыбка
  
Наверх
 
IP записан
 
Переключение на Главную Страницу Страницы: 1
ОтправитьПечать