Форум: "Базы";
Текущий архив: 2002.07.08;
Скачать: [xml.tar.bz2];
ВнизПомогите сваять SQL запрос Найти похожие ветки
← →
Turalyon (2002-06-14 14:35) [0]Спасибо всем кто помог с просмотрами...
В общем все это выдумать пришлось вот по какой причине -
Есть 2 таблицы
1-я Таблица, поля C_id, C_Caption все просто. Ну например Товары.
2-я таблица, поля L_id, C_id (Внешний ключ, ссылка на 1-ю таблицу), L_Date, ... еще какие нить поля. Пусть будет отпуск товаров.
Связь между первой и второй таблицей - один к многим.
Мне нужно получить в результате запроса список отпуска товаров за какое то время... все вроде бы просто. Но мне надо сделать так, чтобы был полный список товаров, и если определенный товар не отпускался за этот период времени то вывести нули или прочерк... вот. Что то я уже туплю к концу недели не могу придумать как это организовать...
Я думал сделать так - сделать view из выдачи товаров за определенный срок, а потом JOIN сделать к 1-й базе... вот для этого и спрашивал про просмотры.
← →
Romkin (2002-06-14 14:47) [1]select t1.C_ID, t1.C_Caption, t2.L_DATE...
from table1 t1 left join table2 t2 on t1.C_ID = t2.C_ID
where t2.L_DATE between :data1 and :data2
что-то вроде этого
← →
Turalyon (2002-06-14 15:10) [2]Вроде этого запроса я уже пробовал...
Проблемма в том что если в условие WHERE написать дату которй нет в базе... то запрос ничего не вернет, в смысле пусто. Т.е. он сначала присоеденит (JOIN) базы а потом выкинет все по условию не нужное... вот.
Было бы здорово сделать что то вроде такого запроса -
Select .... from t1 left join (select .... from t2) on ...
Но она такого не понимает.
← →
Romkin (2002-06-14 15:31) [3]Понятно, тебе надо в любом случае список товаров... Делали :-))
create procedure Sel_tovList(data1 date, data2 date)
returns (C_ID integer, C_CAption varchar(Скока в таблице), L_ID integer, L_date date, ...)
as
declare variable is_out_present integer;
begin
for select C_ID, C_Caption
from Table1
into :C_ID, :C_Caption
do begin
L_date = NULL; /* если расхода нет - пустое поле */
is_out_present = 0;
for select L_ID, l_date, ... from table2 /* сам допиши список */
where C_ID = :C_ID and L_Date >= :Data1 and L_Date <= :data2
into :L_ID, :L_DATE
do begin
is_out_present = 1;
suspend;
end
/* если расхода нет, даем просто товар */
if (is_out_present = 0) then suspend;
end
end
Примерно так, неточности могут быть, но принцип понятен, я думаю
ВЫзов в TQuery соотв select * from Sel_tovList(:data1, :data2)
И параметрам поставить тип DateTime
← →
Turalyon (2002-06-14 15:48) [4]Спасибо. Щас будем пробовать :)
← →
Romkin (2002-06-14 16:02) [5]Сделай индекс на table2 (C_ID, L_Date) - будет все очень быстро.
Да, вместо L_date = NULL; надо бы L_date = NULL; L_ID = NULL; - если не хочешь получить в L_ID ID предыдущей записи :-))
← →
Turalyon (2002-06-17 10:16) [6]>Romkin ©
Вот так я преобразовал то что вы написали... но у меня оно ругается
SQL error code = -104
Unexpected end of command
Помогите разобраться.. плиз.
create procedure SelAll(date1 date, date2 date)
returns (C_ID DECIMAL(18,0), C_NAME varchar(40), C_DESCRIPTION varchar(200),
L_ID DECIMAL(18,0), SOFT_ID DECIMAL(18,0), L_date date, L_WORKTIME integer, L_TIME time)
as
declare variable is_out_present integer;
begin
for select C_ID, C_NAME, C_DESCRIPTION
from Computer
into :C_ID, :C_NAME, :C_DESCRIPTION
do
begin
L_ID = NULL;
L_DATE = NULL;
SOFT_ID = 0;
L_WORKTIME = 0;
L_TIME = NULL;
is_out_present = 0;
for select L_ID, COMP_ID, L_DATE, SOFT_ID, L_WORKTIME, L_TIME from LogTable
where COMP_ID = :C_ID and L_Date >= :date1 and L_Date <= :date2
into :L_ID, :L_DATE, :SOFT_ID, :L_WORKTIME, :L_TIME
do
begin
is_out_present = 1;
suspend;
end
if (is_out_present = 0) then suspend;
end
end
← →
Romkin (2002-06-17 10:43) [7]Ругается скорее всего на declare variable
У тебя IB6 - в IBConsole процедуры обвязываются как в скрипте -
SET TERM ^ ;
create procedure SelAll(date1 date, date2 date) ....
...
END
^
SET TERM ; ^
COMMIT WORK;
И после ^ не должно быть пробелов - сразу перевод строки.
Все дело в том, что ; - разделитель выражений SQL (term) по умолчанию, а в хранимой процедуре он внутри есть, поэтому осуществляется замена разделителя (вместо ^ часто употребляют !!), это непринципиально.
← →
Turalyon (2002-06-17 10:56) [8]Ух. :) Спасибо большое! Заработало. С меня пиво :)
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2002.07.08;
Скачать: [xml.tar.bz2];
Память: 0.46 MB
Время: 0.007 c