Форум: "Базы";
Текущий архив: 2003.08.25;
Скачать: [xml.tar.bz2];
ВнизНЕРЕАЛЬНЫЙ ЗАПРОС Найти похожие ветки
← →
SPIRIT (2003-07-25 06:29) [0]Значит есть таблицы:
Сотрудники:
код
фио
код из профессии
Сдача
код
код сотрудника
код предмета
дата сдачи
предметы
код
наименование
професси
код
наименование
Внимание вопрос:
как сделать запрос вот с такими полями:
код сотрудника, код профессии,дата сдачи 1 предмета, дата сдачи 2 предмета.......дата сдачи н-го предмета
т.е. поле в запросе береться из записи в таблице.
← →
Johnmen (2003-07-25 09:22) [1]Никак.
← →
SPIRIT (2003-07-25 09:31) [2]вот пацаны говорят "используя вложенные SQL запросы" а как конкретно .... не говорят
← →
Johnmen (2003-07-25 09:55) [3]Пусть пацаны не мелют языком, а приведут конкретный запрос...
:)
А то и я могу сказать, что я балерина.:)
← →
Соловьев (2003-07-25 09:59) [4]
> код сотрудника, код профессии,дата сдачи 1 предмета, дата
> сдачи 2 предмета.......дата сдачи н-го предмета
тебе надо чтобы запрос это выдал или прога(в виде отчета)?
если запрос то
> Johnmen © (25.07.03 09:22)
а если отчет, то и без вложеных запросов - только связывание таблиц с условием достаточно.
← →
Zacho (2003-07-25 10:02) [5]Да можно и запросом, только такой запрос придется формировать динамически в приложении, и будет в нем или куча join"ов или вложенных select"ов, и работать будет тормозно :-) Проще сделать это не запросом, а в приложении
← →
SPIRIT (2003-07-25 10:17) [6]1. Формируем основной запрос:
RxQuery1.SQL.Text:=
SELECT P.ID AS PEPLE, P.JOB %TEST_FIELDS
FROM PEOPLE P
%TEST_JOIN
Где PEOPLE - таблица сотрудников.
%TEST_FIELDS, %TEST_JOIN - макросы (см. RxLibrary -> RxQuery)
2. Заполняем макросы.
Для начала посмотрим на предметы:
Query1.SQL.Text:=
SELECT S.ID
FROM SUBJECT S
ORDER BY S.ID
А теперь немного кода для заполнения макросов в запросе 1:
Query1.First;
RxQuery1.MacroByName("TEST_FIELDS").AsString:= "";
RxQuery1.MacroByName("TEST_JOIN").AsString:= "";
while not(Query1.Eof) do
begin
RxQuery1.MacroByName("TEST_FIELDS").AsString:=
RxQuery1.MacroByName("TEST_FIELDS").AsString + ", T" +
Query1.FieldByName("ID").AsString + ".TEST_DATE AS TEST_DATE_" +
Query1.FieldByName("ID").AsString;
RxQuery1.MacroByName("TEST_JOIN").AsString:=
RxQuery1.MacroByName("TEST_JOIN").AsString +
"LEFT OUTER JOIN TEST T" + Query1.FieldByName("ID").AsString +
" ON (T" + Query1.FieldByName("ID").AsString" + ".PEOPLE = P.ID AND T" +
Query1.FieldByName("ID").AsString + ".SUBJECT = " +
( "ID") 1. Формируем основной запрос:
RxQuery1.SQL.Text:=
SELECT P.ID AS PEPLE, P.JOB %TEST_FIELDS
FROM PEOPLE P
%TEST_JOIN
Где PEOPLE - таблица сотрудников.
%TEST_FIELDS, %TEST_JOIN - макросы (см. RxLibrary -> RxQuery)
2. Заполняем макросы.
Для начала посмотрим на предметы:
Query1.SQL.Text:=
SELECT S.ID
FROM SUBJECT S
ORDER BY S.ID
А теперь немного кода для заполнения макросов в запросе 1:
Query1.First;
RxQuery1.MacroByName("TEST_FIELDS").AsString:= "";
RxQuery1.MacroByName("TEST_JOIN").AsString:= "";
while not(Query1.Eof) do
begin
RxQuery1.MacroByName("TEST_FIELDS").AsString:=
RxQuery1.MacroByName("TEST_FIELDS").AsString + ", T" +
Query1.FieldByName("ID").AsString + ".TEST_DATE AS TEST_DATE_" +
Query1.FieldByName("ID").AsString;
RxQuery1.MacroByName("TEST_JOIN").AsString:=
RxQuery1.MacroByName("TEST_JOIN").AsString +
"LEFT OUTER JOIN TEST T" + Query1.FieldByName("ID").AsString +
" ON (T" + Query1.FieldByName("ID").AsString" + ".PEOPLE = P.ID AND T" +
Query1.FieldByName("ID").AsString + ".SUBJECT = " +
Query1.FieldByName("ID").AsString + ") "
end;
RxQuery1.Open;
ну вот пацаны текст дали ...
лучше бы я и не спрашивал ...
← →
Johnmen (2003-07-25 10:28) [7]>SPIRIT ©
Ещё раз повторю, что НИКАКИМ, сколь угодно сложным запросом, задача не решается. А то, что дали тебе пацаны, так это более одного запроса.
>Zacho © (25.07.03 10:02)
Если этот запрос формируется динамически, значит для подготовки данных для него были уже использованы другие запросы. Т.е. уже запрос не один.
← →
Zacho (2003-07-25 11:52) [8]
> Johnmen © (25.07.03 10:28)
Естественно. Одним запросом такое не сделать, по крайней мере в известных мне диалектах SQL :)
← →
SPIRIT (2003-07-25 12:02) [9]так вы сделайте не одним . хоть 20 тью лиж бы работало
← →
ЮЮ (2003-07-28 05:51) [10]SELECT *
FROM
Сотрудники
LEFT JOIN Профессии ON Сотрудники.КодПрофессии = Профессии.Код
LEFT JOIN СдачаПредмет1 ON Сотрудники.Код = СдачаПредмет1.КодСотрудника
...
LEFT JOIN СдачаПредметN ON Сотрудники.Код = СдачаПредметN.КодСотрудника
Где СдачаПредметN - запросы, заранее приготовленные в Access-е и возвращающие не более одной записи на сотрудника(например, последний экзамен по предмету):
SELECT Сдача.*
FROM
(
( код) SELECT *
FROM
Сотрудники
LEFT JOIN Профессии ON Сотрудники.КодПрофессии = Профессии.Код
LEFT JOIN СдачаПредмет1 ON Сотрудники.Код = СдачаПредмет1.КодСотрудника
...
LEFT JOIN СдачаПредметN ON Сотрудники.Код = СдачаПредметN.КодСотрудника
Где СдачаПредметN - запросы, заранее приготовленные в Access-е и возвращающие не более одной записи на сотрудника(например, последний экзамен по предмету):
SELECT Сдача.*
FROM
(
SELECT MAX(код) Код
FROM Сдача
WHERE КодПредмета = 1
GROUP BY КодСотрудника
) ПоследняяСдача
LEFT JOIN Сдача ON ПоследняяСдача.Код = Сдача.Код
В принципе, полученный подзапрос можно затолкать и в основной и динамически формировать основной, сканируя справочник Предметы
← →
Dick Gonsales (2003-07-28 06:54) [11]По мне так в Access это делается так
1. В Access формируется запрос (Query_Prepare) типа
SELECT код сотрудника, код профессии,код предмета, дата сдачи
FROM <..>
2. В Access или в клиентской части делается перекрестный запрос к Query_Prepare. Типа
TRANSFORM First(Query_Prepare.дата сдачи) AS [дата]
SELECT Query_Prepare.код сотрудника, Query_Prepare.код профессии
FROM Query_Prepare
GROUP BY Query_Prepare.код сотрудника, Query_Prepare.код профессии
PIVOT Query_Prepare.код предмета;
/* First можно пременять если гарантировано что для каждого сотрудника, профессии и предмета есть одна дата сдачи, если больше чем одна - то Max или Min (эффект я думаю понятен) */
А вообще для такого рода запросов я бы рекомендовал бы ознакомится с TDecisionQuery (Delphi), потому как в Access эта фишка есть, а допустим в Sybase, Oracle, MSSQL, IB нет...
Гм, и в Paradox нет, я вот вообще не понимаю почему при разработке сейчас некоторые люди для файл сервер БД используют Paradox, а не Access... Но это так, просто...
>> Johnmen Никак
Не сочти за наезд, но чисто любопытно, вот ты даешь советы во многих ветках форума, а сам на чем специализируешься, вот у меня такое впечатление, может ошибочное, что на ANSI SQL 92
← →
SPIRIT (2003-07-28 12:47) [12]Dicck Gonsales
спасибо тебе ОГРОМНОЕ ... помог так помог... блин не передать символами в этом сообщении как я тебе благодарен... самый реальный и самый простой способ подсказал ... 2 минуты и у меня все получилось .... (почему на 2 курсе акцесс не изучал вот я тормоз)
еще раз ПАСИБААААААААААА
← →
SPIRIT (2003-07-28 12:54) [13]да.. я в Access сформировал Query_prepare и к нему перекресный... в работает отлично...
НО.. есть одно НО, может я покажусь наглым... а как сделать для одного предмета две даты... дата предыдущей сдачи и дата следующей .. в Access не дает сделать.. ругается типа можно несколько полей для строк и только одно поле для столбцов и одно поле значений
← →
Dick Gonsales (2003-07-29 00:03) [14]>> SPIRIT
Я не совсем понял твой вопрос...
← →
SPIRIT (2003-07-29 06:56) [15]допустим в таблице СДАЧА добавилось поле Дата след. сдачи т.е. по каждому предмету дата пред. сдачи и дата след. сдачи .... в Access он разрешает только по одной дате делать
в делфи Transform ругается ....
ну должно получиться что то типа:
.......................|экзамен 1 |............| экзамен 2 |
..................|дата пред.|дата след.|дата пред.|дата след.|
Иванов | Механик |..12.12.01.|.12.12.04.|13.12.01..|13.12.04..|
точки: это вместо пробелов
← →
Dick Gonsales (2003-07-31 06:21) [16]Если не надо изменять записи, а это я так понимаю и не надо, то я бы тебе посоветовал в Query_Prepare написать следующее:
SELECT код сотрудника, код профессии,код предмета,
Format([дата пред],"dd-mm-yyyy")+" / "+Format([дата след],"dd-mm-yyyy") AS [Дата пред / Дата след]
FROM <..>
Ну смысл понятен я думаю. И еще на будующее, когда строишь запрос в конструкторе, там есть такая фишка "построить выражение", там ты можешь использовать различные встроенные функции, т.е SELECT function(Field1) FROM Table. Очень иногда помогает, и еще эти функции ты можешь писать сам в секции Модули. Благо HELP по VBA for Access на русском... Иногда очень очень помогает, а на быстродействии практически не сказывается...
← →
SPIRIT (2003-07-31 07:32) [17]Этот запрос потом используется в FastReport (забыл сказать) и эту проблемку я уже решил по другому..
В query_Prepare добавил дату след. сдачи. К нему(запросу) создал два перекрестных запроса : один по дате пред. сдачи другой соответсвенно по след.. И из них уже простой запрос с двумя датами. И в FastReport все красиво получилось. Просто там уже надо к дате след. обращаться, если она меньще текущей, то рисуется красненьким иначе череньким. (Благо FastReport позволяет сделать это очень просто)
P.S. Но все равно огромное тебе С П А С И Б О
← →
passm (2003-07-31 09:19) [18]SPIRIT © (25.07.03 10:17)> Я не "пацаны" :))
Поясняю.
Ты хочешь написать запрос в котором заранее неизвестно количество столбцов. Мне такие SELECT"ы видеть не приходилось. Поэтому необходимо формировать текст запроса при помощи кода. Пример которого я тебе и привел.
← →
SPIRIT (2003-07-31 09:39) [19]Да все у меня работает как посоветовал Dick.. перекресный запрос преобразует записи одной таблицы в поля запроса и не важно сколько их. Все это уже давно придумано разработчиками MS ACCESS. И мне это в течение первых двух курсов пытался вбить мой перпод по информатике (как видим - бестолку). Зачем изобретать велосипед, если он уже есть. И зачем в коде мне писать процедуры, смысл которых я не понимаю. Тем более макросы...зачем ? У меня в ACCESS такие же три запросика (не.. даже 4). А в Delphi я уже с готовым (4-ым) работаю.
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2003.08.25;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.01 c