Перекрестный запрос из двух обычных

DavidKats
Дата: 23.11.2009 06:44:33
Есть таблица, куда заносится ПЛАН отгрузки вида:
Дата, Обозначение изделия, Количество
На основе этой таблицы сделан перекрестный запрос, где по строкам Обозначение, по столбцам - Дата, на пересечении - Количество.

Кроме того, в базе есть таблица ФАКТИЧЕСКИХ отгрузок такого же вида:
Дата отгрузки, Обозначение изделия, Количество

Встала необходимость добавить данные о фактических отгрузках в вышеуказанный перекрестный запрос (план отгрузок).
Иными словами пользователю необходимо одновременно (в соседних строках) видеть сколько на каждую дату ЗАПЛАНИРОВАНО отгрузить и сколько на эту дату отгружено ФАКТИЧЕСКИ.
Подскажите, пожалуйста, как это можно сделать?
-=-
Дата: 23.11.2009 08:10:40
DavidKats, попробуйте такой запрос
TRANSFORM First(Q.Количество) AS c
SELECT Q.pf
FROM (SELECT Дата, Изделие & " (план)" As pf, Количество
      FROM Plan
      UNION ALL
      SELECT F.Дата, F.Изделие & " (план)", 0
      FROM Fact As F LEFT JOIN Plan As P ON F.Дата=P.Дата And F.Изделие=P.Изделие
      WHERE P.Количество Is Null
      UNION ALL 
      SELECT Дата, Изделие & " (факт)", Количество
      FROM Fact
      UNION ALL
      SELECT P.Дата, P.Изделие & " (факт)", 0
      FROM Plan As P LEFT JOIN Fact As F ON F.Дата=P.Дата And F.Изделие=P.Изделие
      WHERE F.Количество Is Null) As Q
GROUP BY Q.pf
PIVOT Format([Дата],"Short Date")
DavidKats
Дата: 24.11.2009 02:41:27
-=-,
Спасибо! В принципе - это то, что нужно!
Немного доработал его под себя:
TRANSFORM Sum(Q.Количество) AS c
SELECT Q.pf, Q.Завод
FROM (SELECT Дата, Обозначение & " (План)" As pf, Завод, Количество
      FROM ПланОтгруз
      WHERE Month(Дата) = Month(GetDate()) and Year(Дата)=Year(GetDate())
      UNION ALL
      SELECT F.[Дата отгрузки] as Дата, F.Обозначение & " (План)", F.Завод, Null
      FROM Отгрузка As F LEFT JOIN ПланОтгруз As P ON F.Дата=P.Дата And F.Обозначение=P.Обозначение
      WHERE P.Количество Is Null AND Month([Дата отгрузки]) = Month(GetDate())  and Year([Дата отгрузки])=Year(GetDate())
      UNION ALL 
      SELECT [Дата отгрузки] as Дата, Обозначение & " (Факт)", Завод, Количество
      FROM Отгрузка
      WHERE Month([Дата отгрузки]) = Month(GetDate()) and Year([Дата отгрузки])=Year(GetDate())
      UNION ALL
      SELECT P.Дата, P.Обозначение & " (Факт)", P.Завод, Null
      FROM ПланОтгруз As P LEFT JOIN Отгрузка As F ON F.Дата=P.Дата And F.Обозначение=P.Обозначение
      WHERE F.Количество Is Null)  AS Q
GROUP BY Q.pf, Q.Завод
PIVOT Format([Дата],"dd\/mm");
Как видно на картинке, вместо Обозначения и Завода запрос подставляет их ключи. Подскажите, пожалуйста, где и как правильно нужно заДЖОИНить чтобы вместо ключей подставились соответствующие значения из справочника?
DavidKats
Дата: 24.11.2009 02:46:12
С полем "Завод" разобрался - просто назначил подстановку в конструкторе.
А как все же быть с полем "Изделие"?
mds_world
Дата: 24.11.2009 08:02:39
DavidKats
А как все же быть с полем "Изделие"?

TRANSFORM Sum(Q.Количество) AS c
SELECT Q.pf, Q.Завод
FROM (SELECT Дата, Обозначение & " (План)" As pf, Завод, Количество
      FROM ПланОтгруз
      WHERE Month(Дата) = Month(GetDate()) and Year(Дата)=Year(GetDate())
      UNION ALL
      SELECT F.[Дата отгрузки] as Дата, F.Обозначение & " (План)", F.Завод, Null
      FROM Отгрузка As F LEFT JOIN ПланОтгруз As P ON F.Дата=P.Дата And F.Обозначение=P.Обозначение
      WHERE P.Количество Is Null AND Month([Дата отгрузки]) = Month(GetDate())  and Year([Дата отгрузки])=Year(GetDate())
      UNION ALL 
      SELECT [Дата отгрузки] as Дата, Обозначение & " (Факт)", Завод, Количество
      FROM Отгрузка
      WHERE Month([Дата отгрузки]) = Month(GetDate()) and Year([Дата отгрузки])=Year(GetDate())
      UNION ALL
      SELECT P.Дата, P.Обозначение & " (Факт)", P.Завод, Null
      FROM ПланОтгруз As P LEFT JOIN Отгрузка As F ON F.Дата=P.Дата And F.Обозначение=P.Обозначение
      WHERE F.Количество Is Null)  AS Q
GROUP BY Q.pf, Q.Завод
PIVOT Format([Дата],"dd\/mm");

В выделеном, вместо таблица "Отгрузка", поставьте
Select *, Наименование 
From Отгрузка Inner Join ТаблицаНаименований On Отгрузка.Обозначение=ТаблицаНаименований.Обозначение
В соответствующих селектах запишите Наименование из этого подзапроса
DavidKats
Дата: 24.11.2009 10:54:39
mds_world,

Не получается. Забыл отметить, что Таблица-справочник имеет следующие поля:
Код (Дл. целое), Обозначение (текстовое)
И вот кажется из-за этого возникает конфликт имен. Аксес мне пишет мол Обозначение может относиться к нескольким таблицам..
И еще вопрос. А почему Вы предлагаете подставить подзапрос только в трех случаях вместо таблицы "Отгрузка"? А в первом случае вместо "ПланОтгруз" разве не нужно подставлять??? Там ведь такая же схема подстановки обозначений изделий из той же таблицы-справочника...

И еще непонятно почему Вы в этом подзапросе в селекте выбираете и звездочку(*) и плюс еще Наименование??
mds_world
Select *, Наименование
From Отгрузка Inner Join ТаблицаНаименований On Отгрузка.Обозначение=ТаблицаНаименований.Обозначение
mds_world
Дата: 24.11.2009 11:42:05
DavidKats
Таблица-справочник имеет следующие поля:
Код (Дл. целое), Обозначение (текстовое)
И вот кажется из-за этого возникает конфликт имен. Аксес мне пишет мол Обозначение может относиться к нескольким таблицам..

Если имена совпадают - обязательно скажет. Чтобы не было лишних разговоров, перед полем, через точку, пишите еще и источник. Типа Запрос.Поле


DavidKats
И еще непонятно почему Вы в этом подзапросе в селекте выбираете и звездочку(*) и плюс еще Наименование??

Так ведь Наименование это и есть поле которое вы хотели видеть на выходе запроса. А звездочка пошла из того, что вы использовали в запросе таблицу, следовательно и все ее поля.
-=-
Дата: 24.11.2009 12:09:20
DavidKats, пробуйте такой запрос
TRANSFORM Sum(Q.Количество) AS c
SELECT Z.Наименование As Завод, I.Наименование & Q.s AS Изделие
FROM ((SELECT QP.* FROM QP
      UNION ALL
      SELECT QF.Дата, QF.Обозначение, QF.Завод, Null," (План)"
      FROM QF LEFT JOIN QP ON QF.Обозначение=QP.Обозначение And QF.Завод=QP.Завод
      WHERE QP.Количество Is Null
      UNION ALL 
      SELECT QF.* FROM QF
      UNION ALL
      SELECT QP.Дата, QP.Обозначение, QP.Завод, Null," (Факт)"
      FROM QP LEFT JOIN QF ON QF.Обозначение=QP.Обозначение And QF.Завод=QP.Завод
      WHERE QF.Количество Is Null) AS Q 
      INNER JOIN Заводы As Z ON Q.Завод=Z.Код) 
      INNER JOIN Изделия As I ON Q.Обозначение=I.Код
GROUP BY Q.Завод, Q.Обозначение, Z.Наименование, I.Наименование & Q.s
PIVOT Format(Q.Дата,"dd\/mm")
где QP и QF - сохраненные запросы:
QP
SELECT Дата, Обозначение, Завод, Количество, " (План)" AS s
FROM ПланОтгруз
WHERE Month(Дата)=Month(GetDate()) And Year(Дата)=Year(GetDate())
QF
SELECT [Дата отгрузки] AS Дата, Обозначение, Завод, Количество, " (Факт)" AS s
FROM Отгрузка
WHERE Month([Дата отгрузки])=Month(GetDate()) And Year([Дата отгрузки])=Year(GetDate())
Заводы - справочник заводов с полями Код, Наименование;
Изделия - справочник изделий с полями Код, Наименование.
DavidKats
Дата: 24.11.2009 12:18:17
Уважаемый mds_world,
А могли бы Вы еще разок просмотреть этот запрос? Я что-то совсем запутался. Подставляет теперь правильно. Но все-таки определенно что-то напутано. Потому что количество строк разное. Если три строки плана, то и факта должно быть столько же и следовать они должны друг за другом (Кстати, а можно ли сделать чтобы было не "План, План, Факт, Факт", а "План, Факт, План, Факт"?)
TRANSFORM Sum(Q.Количество) AS c
SELECT Q.Изделие, Q.Завод
FROM (SELECT Дата, Обозначен & " (План)" As Изделие, Завод, Количество
      FROM  (Select *, Изделие.Обозначение As Обозначен From ПланОтгруз 
Inner Join Изделие On ПланОтгруз.Обозначение=Изделие.[№ МСП]) 
      WHERE Month(Дата) = Month(GetDate()) and Year(Дата)=Year(GetDate())
      UNION ALL
      SELECT F.[Дата отгрузки], F.Обозначен & " (План)", F.Завод, Null
      FROM (Select *, Изделие.Обозначение As Обозначен From Отгрузка Inner Join Изделие On Отгрузка.Обозначение=Изделие.[№ МСП]) As F 
LEFT JOIN ПланОтгруз As P 
ON F.Дата=P.Дата And F.Обозначение=P.Обозначение
      WHERE P.Количество Is Null AND Month([Дата отгрузки]) = Month(GetDate())  and Year([Дата отгрузки])=Year(GetDate())
      UNION ALL 
      SELECT w.[Дата отгрузки], w.Обозначен & " (Факт)", w.Завод, Количество
      FROM  (Select *, Изделие.Обозначение As Обозначен From Отгрузка Inner Join Изделие On
 Отгрузка.Обозначение=Изделие.[№ МСП]) as w
      WHERE Month([Дата отгрузки]) = Month(GetDate()) and Year([Дата отгрузки])=Year(GetDate())
      UNION ALL
      SELECT F.[Дата отгрузки], F.Обозначен & " (Факт)", F.Завод, Null
      FROM ПланОтгруз As P LEFT JOIN (Select *, Изделие.Обозначение As Обозначен From Отгрузка Inner Join Изделие 
On Отгрузка.Обозначение=Изделие.[№ МСП]) As F 
ON F.[Дата отгрузки]=P.Дата And F.Обозначение=P.Обозначение
      WHERE F.Количество Is Null)  AS Q
GROUP BY Q.Изделие, Q.Завод
PIVOT Format([Дата],"dd\/mm");
Таблица "Отгрузка": [Дата отгрузки], Завод, Обозначение, Количество
Таблица "ПланОтгр": Дата, Завод, Обозначение, Количество
Честно говоря, я запутался между F, P, Датой, [Датой Отгрузки] и т.п. Видимо потому, что не совсем понимаю принципа связи частей этого запроса...