Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Внешнее соединение нескольких таблиц в ACCESS

1.8K
01 мая 2010 года
NextTime
217 / / 19.12.2007
Имеется база ACCESS со следующей схемой БД:
[ATTACH]4228[/ATTACH]
Она неидеальна и еще будет миллион раз изменяться, но это не важно, нас сейчас интересует один запрос. По "Накладные" можно определить, какой товар на какой склад, в каком количестве и когда поступил. По "Договоры" можно узнать, какой товар, когда и в каком количестве был продан.
Примерное содержание таблиц:
http://fastpic.ru/view/6/2010/0501/109b2a6a7753f4452e86b9f5de1dd636.png.html
http://fastpic.ru/view/6/2010/0501/feb648281271763f64e2ae9d31132a27.png.html
http://fastpic.ru/view/6/2010/0501/3dde865edf7c3fe928f0740c489d5463.png.html
http://fastpic.ru/view/6/2010/0501/47444441be137c4af061e18d866aef63.png.html
http://fastpic.ru/view/6/2010/0501/1100fd58899282f5d1c9cce34aae7415.png.html
Необходимо определить, какой товар и в каком количестве остался на каких складах на данный момент. Для этого я сделал следующий запрос:
 
Код:
SELECT Накладная.[Код поставщика], Накладная.[Код  склада], Накладная.[Код товара], Накладная.Количество, Договор.Количество, IIf(IsNull([Договор]![Количество]),[Накладная]![Количество],[Накладная]![Количество]-[Договор]![Количество]) AS Осталось
FROM Накладная LEFT JOIN Договор ON Накладная.[Код товара] = Договор.[Код товара];

Схема в конструкторе:
[ATTACH]4229[/ATTACH]
Получившаяся таблица:
[ATTACH]4230[/ATTACH]
Всё получилось правильно, мы узнали количество оставшегося товара. Но какого? У нас же тут "Код_товара", Производитель и модель которого хранится в "Производители" и в "Товар". Но при попытке добавить еще другие таблицы без внешнего соединения, например, так:
[ATTACH]4231[/ATTACH]
Получаем запрос:
 
Код:
SELECT Накладная.[Код поставщика], Накладная.[Код  склада], Производители.[Наименование производителя], Товар.Модель, Накладная.Количество, Договор.Количество, IIf(IsNull([Договор]![Количество]),[Накладная]![Количество],[Накладная]![Количество]-[Договор]![Количество]) AS Осталось
FROM Производители INNER JOIN (Товар INNER JOIN (Накладная LEFT JOIN Договор ON Накладная.[Код товара] = Договор.[Код товара]) ON (Товар.[Код товара] = Накладная.[Код товара]) AND (Товар.[Код товара] = Договор.[Код товара])) ON Производители.[Код производителя] = Товар.[Код производителя];

Выполняться который не хочет, получаем следующую ошибку:
[ATTACH]4232[/ATTACH]
Я пробовал всяко изменять запрос этот: и разбивать на множество запросов и его самого всяко изменять - не помогло. Максимум, что я получал - таблицу как будто без внешнего соединения, в которой отсутствовали пустые записи Договор.Количество.
Прошу помочь. Как мне сделать правильно этот запрос? Чтобы получить количество оставшегося товара (с указанием Производителя и Модели), на каком он складе и кто поставщик (его наименование)
385
04 мая 2010 года
SomewherSomehow
477 / / 25.07.2004
А зачем делать столько вложенных джойнов?
почему нельзя так?
Код:
SELECT
    Накладная.[Код поставщика],
    Накладная.[Код  склада],
    Накладная.[Код товара],
    Накладная.Количество,
    Договор.Количество,
    IIf(IsNull([Договор]![Количество]),[Накладная]![Количество],[Накладная]![Количество]-[Договор]![Количество]) AS Осталось
FROM
    Накладная
    LEFT JOIN Договор ON Накладная.[Код товара] = Договор.[Код товара];
    LEFT JOIN
    (
        select * from Товар
        INNER JOIN Производители ON ON Производители.[Код производителя] = Товар.[Код производителя];
    ) AS Товар2 ON Договор.[Код товара] = Товар2.[Код товара];

либо вообще напрямую
 
Код:
Накладная
    LEFT JOIN Договор ON Накладная.[Код товара] = Договор.[Код товара];
    LEFT JOIN Товар ON Договор.[Код товара] = Товар.[Код товара];
    LEFT JOIN Производители ON ON Производители.[Код производителя] = Товар.[Код производителя];
1.8K
05 мая 2010 года
NextTime
217 / / 19.12.2007
В вашем запросе 275 ошибок:-) исправить не смог:-) во-первых, точка с запятой ставится только лишь в конце запроса, а не в каждой строчке (ошибка: обнаружен символ за пределами запроса), 2 раза друг за другом повторяется "ON". Если исправить это, то начинает ругаться на то, что в выражении после FROM ошибка (отсутствие оператора). Я раньше пробовал несколько внешних связей через JOIN делать - опять получал сообщение про неоднозначность внешних связей


И еще... в Накладной (в этом запросе):
http://forum.codenet.ru/attachment.php?attachmentid=4230&d=1272703902
надо бы просуммировать все Накладная.Количество и Договор.Количество, где Склады совпадают и КОД товара между собой
385
06 мая 2010 года
SomewherSomehow
477 / / 25.07.2004
Ну ясное дело, я Вам проиллюстрировал принцип, а не синтаксис, понятия не имею как там точки с запятыми ставятся, я думаю это уже вы сами должны дописать, или вам разжевать и в рот положить?... А может сам запрос за вас написать?

Что касается соединений, требованиям ansi они отвечают. Так что сообщения заморочки accessa. Проверье правильность создания ключей и ограничений на таблице. Помню когда-то в детстве я использовал акцесс, натыкался на такую ерунду.

Суммируйте, что вам мешает...или хотите опять готовый запрос?

Кстати, русские названия это жесть....

П.С,
Поражают такие люди...
1.8K
07 мая 2010 года
NextTime
217 / / 19.12.2007
Если бы знал, как, то, наверно, бы не спрашивал... А раз спрашиваю...
Допустим, как суммировать? Если просто поставить группировка и Sum(Накладная.Количество) и Sum(КОД товара), то работать не будет, а как по-другому я не знаю...
На подзапросы еще ладно, может и смогу разбить...
Про русский... Так надо... Не моя прихоть...

P.S.: Готовый запрос необязательно, но разобраться как-то нужно.
P.S. 2: Меня тоже много что поражает и что? Лучше бы помогли, нежели умничать...
385
07 мая 2010 года
SomewherSomehow
477 / / 25.07.2004
Предлагаете мне для ВАШЕЙ проблемы создать в акцессе бд и разбираться с синтаксисом, а может просто вы не поленитесь и почитаете документацию к вашей БД.
Sum - всю жизнь так суммировалось, иных способов нет. Понятие "не работает" слишком обширное, я еще понимаю когда так пользователь говорит из-за компьютерной безграмотности, но когда разработчик...да к тому же задавая вопрос на форуме характеризует проблему как "не работает"....

P.S.2 А то что речь не о многом, а о вашем стиле задавать вопросы. "Надо бы просуммировать..", "умничать" - если продолжите в том же духе будет бан.
1.8K
07 мая 2010 года
NextTime
217 / / 19.12.2007
C соединениями сам разобрался.
Про сумму... вы бы поняли, что за ошибка, если посмотрели бы результаты запроса. Забудем, какой запрос был, для простоты есть следующий запрос:
 
Код:
SELECT Поставщики.[Наименование поставщика], [Справочная складов].[Наименование склада], Производители.[Наименование производителя], Товар.Модель, Накладная.Количество
FROM Поставщики INNER JOIN ([Справочная складов] INNER JOIN (Производители INNER JOIN (Товар INNER JOIN Накладная ON Товар.[Код товара] = Накладная.[Код товара]) ON Производители.[Код производителя] = Товар.[Код производителя]) ON [Справочная складов].[Код склада] = Накладная.[Код  склада]) ON ([Справочная складов].[Код поставщика] = Поставщики.[Код поставщика]) AND (Поставщики.[Код поставщика] = Накладная.[Код поставщика]);

Конструктор:
[ATTACH]4245[/ATTACH]
Результат и то, что нужно:
[ATTACH]4246[/ATTACH]
Если одинаковы Наименование склада (точнее КОД склада) и Код товара у нескольких записей, то суммировать нужно Накладня.Количество этих записей. Как это сделать?
385
07 мая 2010 года
SomewherSomehow
477 / / 25.07.2004
Ааа..так вы не разработчик, а для диплома...тогда по идее вам наверное надо было в ветку стеденты..
Но, цените мою любознательность и предпраздничное настроение =)

Ради интереса провел эксперимент, вот такой запрос у меня выполняется без синтаксических ошибок в ms access 2003 (по логике тоже вроде все верно, но это вам виднее должно быть):
Код:
SELECT
        Накладная.[Код поставщика],
        Накладная.[Код склада],
        Товар2.[Наименование производителя],
        Товар2.Модель,
        Накладная.Количество,
        Договор.Количество,
        IIf(IsNull([Договор]![Количество]),[Накладная]![Количество],[Накладная]![Количество]-[Договор]![Количество]) AS Осталось
FROM
        Накладная
        LEFT JOIN
        (
                Договор
                LEFT JOIN
                (
                        SELECT
                                Товар.[Код товара],
                                Производители.[Наименование производителя],
                                Товар.Модель
                        FROM
                                Товар
                                INNER JOIN Производители ON Товар.[Код производителя] = Производители.[Код производителя]
                ) AS Товар2 ON Договор.[Код товара] = Товар2.[Код товара]
        ) ON Накладная.[Код товара] = Договор.[Код товара];

Вообще и приведенный в предыдущем посте запрос должен был работать (если убрать опечатки копи-пасты), но, как я и предполагал, акцесс имеет оригинальный взгляд на многие вещи из мира субд (очередность скобок в джойнах?..бррр..), иногда не очень логичные, так что сочувствую вам в вашем выборе бд.
1.8K
07 мая 2010 года
NextTime
217 / / 19.12.2007
Не видел ваш пост, сделал сам. яху!!!:-)
385
07 мая 2010 года
SomewherSomehow
477 / / 25.07.2004
Поздравляю!

Если б вы сами сделали яху вы были бы миллиардером =)
типа шутко=)

С суммированием по идее тоже должно получиться через группировку по нужному полю и агрегату sum()
1.8K
07 мая 2010 года
NextTime
217 / / 19.12.2007
Вот, что я хотел с самого начала.
Таблица Накладная:
[ATTACH]4249[/ATTACH]
Содержание остальных таблиц:
http://fastpic.ru/view/6/2010/0501/109b2a6a7753f4452e86b9f5de1dd636.png.html
http://fastpic.ru/view/6/2010/0501/feb648281271763f64e2ae9d31132a27.png.html
http://fastpic.ru/view/6/2010/0501/3dde865edf7c3fe928f0740c489d5463.png.html
http://fastpic.ru/view/6/2010/0501/47444441be137c4af061e18d866aef63.png.html
http://fastpic.ru/view/6/2010/0501/1100fd58899282f5d1c9cce34aae7415.png.html

Получившийся запрос:
 
Код:
SELECT Поставщики.[Наименование поставщика], [Справочная складов].[Наименование склада], Производители.[Наименование производителя], Товар.Модель, Sum(Накладная.Количество) AS [Сумма по накладной], Sum(Договор.Количество) AS [Сумма по договору], IIf(IsNull(Sum([Договор]![Количество])),Sum([Накладная]![Количество]),Sum([Накладная]![Количество])-Sum([Договор]![Количество])) AS [Остаток на складе]
FROM (Поставщики INNER JOIN ([Справочная складов] INNER JOIN (Производители INNER JOIN (Товар INNER JOIN Накладная ON Товар.[Код товара] = Накладная.[Код товара]) ON Производители.[Код производителя] = Товар.[Код производителя]) ON [Справочная складов].[Код склада] = Накладная.[Код  склада]) ON (Поставщики.[Код поставщика] = [Справочная складов].[Код поставщика]) AND (Поставщики.[Код поставщика] = Накладная.[Код поставщика])) LEFT JOIN Договор ON Товар.[Код товара] = Договор.[Код товара]
GROUP BY Поставщики.[Наименование поставщика], [Справочная складов].[Наименование склада], Производители.[Наименование производителя], Товар.Модель, Накладная.[Код  склада], Товар.[Код товара];


конструктор:
[ATTACH]4250[/ATTACH]
Результат запроса:
[ATTACH]4251[/ATTACH]
Как видим, всё сложилось нормально и мы получили остаток на складе на данный момент. Пришлось убрать несколько лишних связей, которые переносились из схемы БД. Внешне работает нормально, пытался проверять, но,если можете, топроверьте за мной:-)
Access формирует весь запрос в одну строчку... А смотреть приятнее на форматированный код. Есть ли каки-нибудь инструменты для переформатирования кода (не только для SQL, но и для других языков можно).
P.S. Да, согласен, Microsoft вечно в своих продуктах делает кривую поддержку стандартов.
Это как с баша (да простят меня добрые модеры за цитирование мата и оффтоп)
http://bash.org.ru/quote/406181
Цитата:
xxx:
С ленты:
Microsoft насчитала 2000 несовместимых с IE8 сайтов.
Через год после выпуска последней версии Internet Explorer Microsoft подвела статистику соответствия нескольких тысяч популярных сайтов требованиям браузера.
Доля сайтов, которые полностью соответствуют заданным IE8 стандартам, составила 19 процентов.

xxx:
Вся рота не в ногу. Один старшина, *****, в ногу.

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог