Страница 1 из 1

Подскажите, как можно сделать запрос

Добавлено: 23 фев 2008, 16:17
Kotъ-Begemotъ
Есть таблица районов REGION (REGID (PK), REGNAME, MACROREG) где MACROREG - расширенный "регион" в который могут входить несколько районов.

Есть таблица исполнителей UNITS в которой есть поле HOME, содержащее ID региона куда исполнитель желал бы отправиться :)

Есть таблица заказов ORDERS в которой нас интересует только поле REGTO - регион куда направлен заказ.

Задача - прицепить к таблице ORDERS некое поле ISHOME которое покажет есть ли в таблице исполнителей хотя бы один человек, который хочет направиться в район, входящий в тот же регион, в который входит REGTO из таблицы заказов.

Для простоты расскажу человеческим языком :) Водитель просит диспетчера отправить его "домой" с заказом. То есть взять заказ, уехать в район проживания, и закончить работу. Диспетчер ставит ему пометку этого региона (поле HOME таблицы UNITS). Появляется заказ, ведущий в тот же регион, к которому принадлежит желаемый район отправки для водителя. Заказ должет быть помечен специальной пометкой, чтобы диспетчер видел, что есть желающий(ие) отправиться туда "с последнм заказом".

Раньше делал так:
Создавал Calculated поле IsHome которое обсчитывалось в OnCalcFields с помощью выполнения запроса:

Код: Выделить всё

SELECT UN.UNITID FROM UNITS UN
WHERE UN.HOME IN
(
SELECT RG.REGID
FROM REGION RG
WHERE RG.MACROREG IN
 (SELECT RG1.MACROREG
  FROM REGION RG1
  WHERE RG1.REGID = :REGTO
 )
)
А как бы это сделать по-человечески? Надо что то вроде поля, которое формируется по условию EXISTS что-ли...

Прикол еще в том, что поле должно быть именно динамическим. Нельзя физически создать поле и заполнять при добавлении заказа, потому что пометка с водителя может быть снята в любой момент, и надо, чтобы в этом случае пропала пометка и с заказа...

Добавлено: 23 фев 2008, 16:49
kdv
www.ibase.ru/devinfo/joins.htm
прочитай наконец, пожалуйста.

Добавлено: 23 фев 2008, 17:32
Kotъ-Begemotъ
kdv писал(а):www.ibase.ru/devinfo/joins.htm
прочитай наконец, пожалуйста.
Хорошо, прочитаю еще раз. Но что в условие ON ставить-то?!? Там и так уже запрос:

Код: Выделить всё

SELECT OD.ORDERID, OD.CLIENTID, OD.GETTIME, OD.STREETID, OD.HOUSE,
       OD.FLAT, OD.CHGBIND, OD.TARGETID, OD.LOCALE, OD.START, OD.FINISH, OD.ADVTIME,
       OD.ORDTYPEID, OD.DONEID, OD.DISTANCE, OD.ORGORDER, OD.PHONE, 
       OD.UNCOMF, OD.VOLUNTARY, OD.TIMPRES, OD.RECV, OD.SEND, OD.REGID, OD.RECL,
       OD.RPT, OD.ANYCAR, OD.LNGORD, OD.NEEDREM, OD.QUEST, OD.ORGSUM, OD.FORLAST,
       OD.GARANT, OD.VIPTYPE, OD.BONUS, OD.NOCARS, OD.RENTCAR, OD.ASGARANT,
       OD.ONLYVIP, OD.USEBONUS, OD.RESEND, OD.ORGCARDNUM, OD.TIMWAIT,
       OD.SECTORID, OD.PHCHANEL, OD.UNITID, OD.CARID, OD.PEOPLEID, OD.TAXID,
       OD.NOTIFYTIME,
       ST.STREETNAME STREETFROM, ST.REGID REGIDFROM,
       TG.STREETNAME STREETTO, TG.REGID REGIDTO,
       RF.REGNAME REGFROM, RT.REGNAME REGTO, RT.PROBLEM TOREGPROBLEM,
       CL.CLIENTNAME, CL.CLIENTID, CL.CLITYPE,
       OG.ORGNAME,
       OT.ORDTYPENAME,
       OY.ORDDONENAME, OY.INFOCOLOR, OY.PATHCOLOR, OY.STATUSCOLOR, OY.BGCOLOR,
       OY.SELCOLOR, OY.NOSELCOLOR,
       US.FULLNAME WHORECV, MU.FULLNAME WHOSEND,
       PL.PNAME DRIVER,
       CR.MARKNAME, CR.MODELNAME, CR.SLANGNAME, CR.TYPENAME, CR.CARCOLOR,
       CR.CARNUMBER, CR.RENT, UN.UNITNAME
FROM ORDERS OD
 JOIN ORDONTYP OY
  ON (OY.ORDDONEID = OD.DONEID)
 JOIN ORDTYPE OT
  ON (OT.ORDTYPEID = OD.ORDTYPEID)
 JOIN STREET ST
  ON (ST.STREETID = OD.STREETID)
 JOIN STREET TG
  ON (TG.STREETID = OD.TARGETID)
 LEFT JOIN REGION RF
  ON (RF.REGID = ST.REGID)
 LEFT JOIN REGION RT
  ON (RT.REGID = TG.REGID)
 LEFT JOIN MUSERS US
  ON (US.USERID = OD.RECV)
 LEFT JOIN MUSERS MU
  ON (MU.USERID = OD.SEND)
 LEFT JOIN CLIENTS CL
  ON (CL.CLIENTID = OD.CLIENTID)
 LEFT JOIN ORGREF OG
  ON (OG.ORGCARDNUM = OD.ORGCARDNUM)
 LEFT JOIN CARS CR
  ON (CR.CARID = OD.CARID)
 LEFT JOIN PEOPLES PL
  ON (PL.PEOPLEID = OD.PEOPLEID)
 LEFT JOIN UNITS UN
  ON (UN.PEOPLEID = PL.PEOPLEID)
WHERE
     @@WHERE_CLAUSE% 1 = 1 @

ORDER BY ORDERID
Ну, WHERE формируется в соответствии с тем, что задано отображать...

Мне же нужен просто факт того, что ЕСТЬ такие водители, у которых HOME принадлежит тому же региону, что и REGTO таблицы ORDERS (которое в свою очередь вытаскивается по JOIN)...

Добавлено: 24 фев 2008, 11:34
Кузнецов Евгений
Доброго времени суток!
Kotъ-Begemotъ писал(а): Хорошо, прочитаю еще раз. Но что в условие ON ставить-то?!?
Проще всего - добавить подзапрос в Select-часть.
(select first 1 - а дальше уже нормальный запрос без IN)

Добавлено: 03 мар 2008, 22:10
Kotъ-Begemotъ
В общем попробовал - бесполезно. Во-первых сложно такой запрос написать, который мои критерии уитывает, но это ерунда, может я еще некомпетентен... Но вот когда я что-то похожее на правду написал, оно выполнялось 8 с лишним секунд... А это неприемлимо в принципе! Поэтому лучше уж с вычисляемыми полями...

Добавлено: 03 мар 2008, 23:12
Кузнецов Евгений
Доброго времени суток!
Kotъ-Begemotъ писал(а):Но вот когда я что-то похожее на правду написал, оно выполнялось 8 с лишним секунд... А это неприемлимо в принципе! Поэтому лучше уж с вычисляемыми полями...
Сомневаюсь, что при полном выборе набора данных на клиента вычисляемые поля дадут фору подзапросу. Как делали (просьба привести только текст подзапроса)?

Добавлено: 04 мар 2008, 09:39
kdv
оно выполнялось 8 с лишним секунд...
сильно сомневаюсь, что для оперативной информации пользователю надо такое количество полей и выборка из такого количества таблиц.
кроме того, много непонятных left join.

Добавлено: 28 мар 2008, 12:49
Kotъ-Begemotъ
kdv писал(а):сильно сомневаюсь, что для оперативной информации пользователю надо такое количество полей и выборка из такого количества таблиц.
Траст ми. Надо. Именно всё что там есть и еще немножко :)
kdv писал(а):кроме того, много непонятных left join.
Ну от части избавлюсь, но вообще нужны именно лефт джойны, так как заказ должен быть выбран независимо от того назначен ему водитель или нет, и так далее и тому подобное... Где соответствие точно будет, там просто джойны стоят. А где может быть а может не быть, там лефт-джойны.