Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Базы данных и репортинг > помогите с SQL -запросом


Автор: FireAlex 19.4.2005, 08:00
база на MSAccess, ado
такие таблицы.
tblDATE
--------------------------
DateId : счетчик
fldate : DateTime


tblOstatok
----------------------
IdOperator : integer
DateId : integer
Ostatok : integer

tblOperator
-------------------------
IdOperator : счетчик
FIO : string

в таблице tblOstatok по датам и операторам хранится остаток товара (в штуках).
нужно написать такой запрос чтобы выдал список операторов и остаток товара на заданную дату ближайшую слева или равную ей. дата задается как параметр.
то есть допустим задаю дату 12.12.2004 - находится запись в таблице tblOstatok с датой, меньшей или равной 12.12.2004
и выводится FIO оператора, дата, и остаток на эту дату и так далее по всем операторам...
проблема как определить такую дату?

Автор: DDX 19.4.2005, 08:33
FireAlex
Если честно, не понял твой вопрос. тебе нужно помочь составить запрос, или сделать дату пареметром, или проблема в том, чтобы найти равную или первую по меньшинству?

если дата нужна как параметр, то в тексте запрос пишешь что-то типа

"... tblDATE.flDate<= [Дата:].."

если нужна первая совпадающая, или меньше, что-то типа того:

Код

select FIRST (tblDATE.flDate) ... FROM ... 
GROUP BY <выражение высичления остатка, оператор> ... 
HAVING (((First(tblDATE.flDate))<=[Дата:]))
ORDER BY First(tblDATE.flDate) DESC;

Автор: DimW 19.4.2005, 09:04
Код

SELECT 
 tOP.FIO
,tD.flDATE
,tOST.OSTATOK
FROM 
 tblDATE         tD
,tblOSTATOK   tOST
,tblOPERATOR tOP
WHERE tD.flDATE<=:pDATE
     AND tOST.DateId = tD.DateId
     AND tOP.IdOperator=tOST.IdOperator 


Если я тебя правильно понял, то запрос будет возвращать оператора который формировал остаток на дату>=указанную дату.
Добавлено @ 09:13
Цитата
если дата нужна как параметр, то в тексте запрос пишешь что-то типа

"... tblDATE.flDate<= [Дата:].."


DDX можешь пояснить что это - [Дата:]?
что то я не встречал такова синтаксиса в SQL...
обычно параметр указывается как - :Дата
smile

Автор: DDX 19.4.2005, 09:33
DimW
этоя применительно к Access, на автопилоте)
ты конечно прав

только ты ещё, кажется, пропустил AS при задании таблиц:
tblDATE tD
,tblOSTATOK tOST
,tblOPERATOR tOP
smile)))))

Автор: DimW 19.4.2005, 09:40
Цитата
только ты ещё, кажется, пропустил AS при задании таблиц:
tblDATE tD
,tblOSTATOK tOST
,tblOPERATOR tOP
)))))


а ты праверь!!! smile smile

Автор: DDX 19.4.2005, 09:46
и правда!) smile
век живи - век учись)
DimW, извини..

Автор: DimW 19.4.2005, 13:02
Цитата
DimW, извини..


ды ладно че ты... smile

Автор: FireAlex 22.4.2005, 08:57
наконец то руки дошли...smile
ваши запросы немного не работают в том плане что выводится список всех операторов у которых остаток <=:pDate
и ещё нельзя использовать псевдоним tOp - это я к DimW:)...
я наваял в итоге такой запрос но он выводит повторяющиеся записи: скажем

оператор1 12.12.2004 100
оператор1 13.12.2004 200

pDate = 14.12.2004. нужно чтобы первую строку не выводил.

подскажите что не так в этом запросе:

Код

SELECT FIRST (tD.fldDateTime), 
            tOst.fldOstatok, 
            tOper.fldFIO
FROM tblDATE         tD,
          tblOstatok    tOSt, 
          tblOperators tOper
WHERE  
          tOst.fldDateId  = tD.fldDateId
  AND  tOper.IdOperator = tRest.fldIdOperator
GROUP BY 
   tOper.fldFIO,
   tOst.fldRestSim, 
   tOper.fldFIO
HAVING ((FIRST (tD.fldDateTime))<=:pDate)
ORDER BY First(tD.fldDateTime) DESC;





Автор: DimW 22.4.2005, 09:19
Цитата
и ещё нельзя использовать псевдоним tOp - это я к DimW:)...


Аргументы пожалуйста...

Цитата
я наваял в итоге такой запрос но он выводит повторяющиеся записи: скажем

оператор1 12.12.2004 100
оператор1 13.12.2004 200


это можно решить так:

Код

SELECT 
 tOP.FIO
,MAX(tD.flDATE)
,tOST.OSTATOK
FROM 
 tblDATE         tD
,tblOSTATOK   tOST
,tblOPERATOR tOP
WHERE tD.flDATE <= :pDATE
     AND tOST.DateId = tD.DateId
     AND tOP.IdOperator = tOST.IdOperator
GROUP BY tOP.FIO,tOST.OSTATOK



Автор: FireAlex 22.4.2005, 11:05
по первой части:
Цитата

и ещё нельзя использовать псевдоним tOp - это я к DimW:)...
Аргументы пожалуйста...


а ты попробуй.
TOP -эта такая инструкция SQL и когда пытаюсь выполнить твой запрос то получаем месагу -
SYNTAX ERROR in FROM CLAUSE.

кстати твой новый запрос
Код

SELECT 
 tOP.FIO
,MAX(tD.flDATE)
,tOST.OSTATOK
FROM 
 tblDATE         tD
,tblOSTATOK   tOST
,tblOPERATOR tOP
WHERE tD.flDATE <= :pDATE
     AND tOST.DateId = tD.DateId
     AND tOP.IdOperator = tOST.IdOperator
GROUP BY tOP.FIO,tOST.OSTATOK

тоже дублирует операторов...

Автор: DimW 22.4.2005, 13:09
Цитата
TOP -эта такая инструкция SQL и когда пытаюсь выполнить твой запрос то получаем месагу -
SYNTAX ERROR in FROM CLAUSE.


сори... smile

Цитата
тоже дублирует операторов...

мда, не досмотрел...

запрос нехочит решаться стандартным SQL... smile

Автор: Dimich 22.4.2005, 13:41
Код
select fio, maxd.fldate, ostatok
from tblOstatok, tblOperator,
(
select tbloperator.idoperator, tbldate.dateid, max (fldate) fldate
from tbldate, tbloperator, tblostatok
where tbldate.dateid = tblostatok.dateid
  and tblostatok.idoperator = tbloperator.idoperator
  and tbldate.fldate <= :p_date
group by tbloperator.idoperator, tbldate.dateid
) maxd
where tblOstatok.idoperator = tbloperator.idoperator
  and tblOstatok.idoperator = maxd.idoperator
  and tblOstatok.dateid = maxd.dateid

З.Ы. В Оракле будет работать, если ошибок синтаксических не наделал, а в аксесе должно....

Автор: Dimich 22.4.2005, 14:10
Не спешите пробовать - не правильно работает вложенный селект, зараза

Автор: Dimich 22.4.2005, 15:16
Вот рабочий вариант, только оговорка - таблица tbldate должна иметь уникальность по полю fldate
Код
select tbloperator.fio, tblostatok.ostatok, tbldate.fldate
from tbloperator, tblostatok, tbldate
where tbloperator.idoperator = tblostatok.idoperator
  and tbldate.dateid = tblostatok.dateid
  and (tblostatok.idoperator, tbldate.fldate) in
(
select tblostatok.idoperator, max (tbldate.fldate) fldate
from tbldate, tblostatok
where tbldate.dateid = tblostatok.dateid
  and tbldate.fldate <= :p_date
group by tblostatok.idoperator
)

Автор: DimW 26.4.2005, 07:47
Dimich, как я и предпологал такая конструкция в аксэсе не прокатила (говорит, что из подчененного запроса невозможно возвратить более одного поля ), а в оракле наура!!! По моему (касательно аксэса) праблема такова селекта не решаема...

Темнемение, такую структуру я встретил первый раз, даже вчера ее уже исмользовал (удобно блин!!!!). Dimich держи законный + smile

FireAlex - если умудришься, не забывай об остальных!!! smile

Автор: Veniamin 15.5.2008, 23:09
база в Access, приложение на Delphi соединено через ADO. Хочу сделать запрос на вывод всех записей из главной таблицы в которых кабинеты следующие 211, 213. Пишу следующее:
Код

DM.QRep1.Active:=false;
      DM.QRep1.SQL.Clear;
      DM.QRep1.SQL.Add('SELECT * FROM [главная таблица]');
      DM.QRep1.SQL.Add('WHERE кабинет IN (211,213)');
      DM.QRep1.Active:=true;
      FindResultForm.ShowModal;


При выполнении запроса выводится следующее: Несоответствие типов данных в выражении условия отбора. В чём причина? 

А если писать так: 
Код

DM.QRep1.SQL.Add('WHERE кабинет IN ('211','213')');

то выводится след.ошибка : Missing operator or semicolon

В главной таблице все поля имеют тип текстовый, кроме номера, он имеет тип - счётчик.

Проверил в Query Analyzer-е SQL-Server 2000 подобный запрос
Код

SELECT * FROM Main WHERE product IN ('хлеб', 'пиво');

 - всё работает, выводит все поля с заданным условием, а с Access что не так?

Автор: Deniz 16.5.2008, 06:26
Dimich, DimW, а почему не попробовать вместо:
Код
select ... where ...
  and (tblostatok.idoperator, tbldate.fldate) in
(
select tblostatok.idoperator, max (tbldate.fldate) fldate
from tbldate, tblostatok
where tbldate.dateid = tblostatok.dateid
  and tbldate.fldate <= :p_date
group by tblostatok.idoperator
)

Код
select ... where ...
  and tbldate.fldate in
(
select max (tbldate.fldate) fldate
from tbldate, tblostatok  ost2
where tbldate.dateid = tblostatok.dateid
  and tbldate.fldate <= :p_date
  and ost2.idoperator = tblostatok.idoperator
)


Добавлено через 1 минуту и 46 секунд
Veniamin, создай новое сообщение.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)