Запрос-барбос

DavidKats
Дата: 03.11.2009 13:33:45
Есть два подразделения. Одно отгружает на заводы и второму подразделению, которое в свою очередь отгружает полученное своим контрагентам. Отчет об отгрузке выводит результаты по ОБОИМ подразделениям. И вот тут задача в том, чтобы не задваивалось количество тех изделий, которые были отгруженны с первого на второе подразделение, а затем на завод. Идентифицировать подразделение можно по полю исполнитель.
Исходный запрос: (здесь количество задваивается)
SELECT Отгрузка.Обозначение, Отгрузка.Завод, Отгрузка.Количество, 
Отгрузка.[Дата отгрузки],  Отгрузка.[Цена АК], Отгрузка.[Количество]*[Цена АК] 
AS [Сумма АК], Отгрузка.Цена AS [Цена МСП], Отгрузка.[Количество]*[Цена] AS [Сумма МСП], 
Отгрузка.[Цена ВР], Отгрузка.Количество*[Цена ВР] AS [Сумма ВР], 
Отгрузка.Исполнитель, Отгрузка.СчФактАК, Отгрузка.СчФактМСП, Отгрузка.СчФактВР
FROM Отгрузка
WHERE (((Отгрузка.[Дата отгрузки]) Between GetPeriodS() And GetPeriodPo()));
mds_world
Дата: 03.11.2009 13:54:21
DavidKats,
может быть так, для каждого исполнителя в отдельности
WHERE (((Отгрузка.[Дата отгрузки]) Between GetPeriodS() And GetPeriodPo())) 
And Отгрузка.Исполнитель="Завод"
Если в отчете нужны все исполнители, то можно соединить запросы по исполнителям через Union All или сделать запрос с группировкой
DavidKats
Дата: 03.11.2009 14:04:03
mds_world,

Не понял что значит "в отдельности"??
В любом случае вижу, что нужно добавить два поля "Количество1" и "Количество2" (по подразделениям)
Но для этого нужно прописать внутри еще два подзапроса. В этом и сложность. Я попробовал. написал так:
SELECT Отгрузка.Обозначение, Отгрузка.Завод, kl.Количество as Количество1, 
Отгрузка.[Дата отгрузки],  Отгрузка.[Цена АК], Отгрузка.[Количество]*[Цена АК] 
AS [Сумма АК], Отгрузка.Цена AS [Цена МСП], Отгрузка.[Количество]*[Цена] AS [Сумма МСП], 
Отгрузка.[Цена ВР], Отгрузка.Количество*[Цена ВР] AS [Сумма ВР], 
Отгрузка.Исполнитель, Отгрузка.СчФактАК, Отгрузка.СчФактМСП, Отгрузка.СчФактВР
FROM Отгрузка
Left Join (Select k.Обозначение, k.Количество From Отгрузка as k Where k.Исполнитель=20 And
k.[Дата отгрузки] Between GetPeriodS() And GetPeriodPo()) as kl 
On Отгрузка.Обозначение= kl.Обозначение 
WHERE (((Отгрузка.[Дата отгрузки]) Between GetPeriodS() And GetPeriodPo()));
Но тут вылазят ошибки.
mds_world
Дата: 03.11.2009 15:08:16
А если прямо в SELECT записать новый подзапрос. Типа такого
SELECT Отгрузка.Обозначение, Отгрузка.Завод, 
(Select First(k.Количество) From Отгрузка as k Where k.Исполнитель=20 
And k.[Дата отгрузки] Between GetPeriodS() And GetPeriodPo() 
And k.Обозначение=Отгрузка.Обозначение And k.Исполнитель=20 ) as Количество1,
Отгрузка.[Дата отгрузки],  Отгрузка.[Цена АК], Отгрузка.[Количество]*[Цена АК] 
AS [Сумма АК], Отгрузка.Цена AS [Цена МСП], Отгрузка.[Количество]*[Цена] AS [Сумма МСП], 
Отгрузка.[Цена ВР], Отгрузка.Количество*[Цена ВР] AS [Сумма ВР], 
Отгрузка.Исполнитель, Отгрузка.СчФактАК, Отгрузка.СчФактМСП, Отгрузка.СчФактВР
FROM Отгрузка
WHERE (((Отгрузка.[Дата отгрузки]) Between GetPeriodS() And GetPeriodPo()));
Здесь First добавлено для вывода только одной записи.

Джойнить, наверняка быстрее будет, но для этого надо знать структуру таблиц и связи между ними.
DavidKats
Дата: 03.11.2009 16:00:32
mds_world

Джойнить, наверняка быстрее будет, но для этого надо знать структуру таблиц и связи между ними.

А таблица-то одна - Отгрузка. все подзапросы ведь тоже по этой таблице.
Структура ее такая:
Код - Счетчик
Обозначение - Числовой (подстановка из справочника)
Дата отгрузки - Дата
Количество - длинное целое
Цена - денежный
Завод - Числовое (подстановка из справочника)
Исполнитель - Числовое (подстановка из справочника)
Остальные поля в расчетах не учавствуют, => тип не принципиален
mds_world
Дата: 03.11.2009 16:10:48
DavidKats,
так сработало или нет с подзапросом в селекте?
DavidKats
Дата: 03.11.2009 16:27:37
mds_world
DavidKats,
так сработало или нет с подзапросом в селекте?

Сработало.. но почему-то некоторые строки "Количество1" пустые...
Папа Игорь
Дата: 03.11.2009 16:29:31
DavidKats
...Идентифицировать подразделение можно по полю исполнитель.


А чем Вы идентифицируете (мля, язык сломаешь) открузку на второе подразделение?
Если идентификация есть, то и фильтруйте по ней чтобы эти записи не попали в запрос.

P.S. А у Вас всегда соблюдается "Одна огрузка = Одно изделие"?
mds_world
Дата: 03.11.2009 16:57:03
DavidKats
Сработало.. но почему-то некоторые строки "Количество1" пустые...

Надо проанализировать почему именно эти оказались пустыми. Может быть не хватает связи, не исключено, что подзапрос возвращает несколько записей, но первая из них (First) пустая.
После того как вы отладите подзапрос в селекте можно будет попытаться его сджойнить.
DavidKats
Дата: 03.11.2009 18:49:27
mds_world,
Так... я тут подумал, .....в общем ЧТО нужно делать я понял точно. Осталось теперь понять КАК это сделать. Вот тут мне ваша помощь и понадобится.
Короче говоря, к исходному запросу приклеиваю:
Left join (Select k.Обозначение, k.Количество From Отгрузка as k Where k.[Дата отгрузки] Between GetperiodS() And GetperiodPo() 
And k.Исполнитель=20) as KL On Отгрузка.Обозначение =KL.Обозначение
и добавляю на вывод поле KL.Количество
Получаем:
SELECT Отгрузка.Обозначение, Отгрузка.Завод, Отгрузка.[Дата отгрузки], Отгрузка.[Цена АК], Отгрузка.[Количество]*[Цена АК] AS [Сумма АК], 
Отгрузка.Цена AS [Цена МСП], Отгрузка.[Количество]*[Цена] AS [Сумма МСП], Отгрузка.[Цена ВР], Отгрузка.Количество*[Цена ВР] AS [Сумма ВР], 
Отгрузка.Исполнитель, Отгрузка.СчФактАК, Отгрузка.СчФактМСП, Отгрузка.СчФактВР, KL.Количество
FROM Отгрузка 
Left join (Select k.Обозначение, k.Количество From Отгрузка as k Where k.[Дата отгрузки] Between GetperiodS() And GetperiodPo() 
And k.Исполнитель=20) as KL On Отгрузка.Обозначение =KL.Обозначение
WHERE (((Отгрузка.[Дата отгрузки]) Between GetPeriodS() And GetPeriodPo()));
Спотыкаюсь о следующее:
Отдельно запрос работает корректно. Выбирает три позиции и их количество, которые были отгружены Исполнителем=20. Но когда этот запрос приклеен Left Join-ом, то количество в соответствующей колонке появляется НЕ ТОЛЬКО там, где Исполнитель=20, но и во всех других случаях, где совпадает Обозначение, но исполнитель там вовсе другой. ПОЧЕМУ ТАК ПРОИСХОДИТ??
На рисунке показаны результаты запросов. Может быть это прояснит ситуацию..