Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

SQL запрос [D7, dBase, FoxPro]


NILLO ©   (2005-11-28 13:19:00) 

Здравствуйте. У меня возникла следующая проблема: Пишу прогу на Delphi 7 используя компонент Query. Делаю SQL запрос к файлам БД (Paradox), а именно CashPay.db и CashSail.db. В первой таблице содержатся следующие поля “CashNumber” (числовой), “ZNumber”(числовой), “ChackNumber”(числовой), “PayedRub” (денежный). Во второй “CashNumber” (числовой), “ZNumber”(числовой), “ChackNumber”(числовой), Date (дата). Использую следующий запрос:
SELECT S.CashNumber, S."Date", COUNT (P.PayedRub)
FROM CashSail S, CashPay P
WHERE (P.ZNumber = S.Znumber)
AND (P.CheckNumber = S.CheckNumber)
AND (S."Date" BETWEEN ‘18.10.2005’ AND ‘19.10.2005’)
GROUP BY S.CashNumber, S."Date";
Этот запрос выводит следующие значения:
Date              | Count (PlayedRub)
18.10.2005     256
19.10.2005    122
Это все работает, все хорошо. Суть проблемы в том что необходимо добавить еще несколько не существующих полей. В которых бы отбирались данные из поля PlayedRub. В первое поле выодилось число записей у которых значение PlayedRub < 50, во второе от 50 до 100 и т.д. Что то вроде этого:
SELECT S.CashNumber, S."Date", COUNT (P.PayedRub), COUNT (P.PayedRub < 50),
FROM CashSail S, CashPay P…
И получился уже такой вид:
Date            | Count (PlayedRub< 50) | Count (PlayedRub>50 но <100) | Count (PlayedRub)
18.10.2005 |156     | 100              | 256
19.10.2005 | 11     | 111              | 122
Если это возможно, то подскажите как это реализовать.


NILLO   (2005-11-29 11:17:00) [1]

Использую Query. А обхожусь без BDE, указывая путь к базе в свойство
"DatabaseName".


evvcom   (2005-11-28 16:43:00) [2]


> и мобильной работать на любом компе без дополнительных приложений.

Насколько я понял, парадокс ты используешь? Насколько мне известно с парадоксом без BDE даже ADO не работает. Т.е. без установки BDE выходит не обойтись.
Какие компоненты доступа используешь?


NILLO   (2005-11-28 16:23:00) [3]

Клиент-сервер сразу отпадает программа должна быть автономной (без привязки к чему либо) и мобильной работать на любом компе без дополнительных приложений.


evvcom   (2005-11-28 16:03:00) [4]

Да! Есть еще способ. Смотри "Local SQL VIEWs". То, что в [2] 2. в скобках: select ... union select ... загоняешь в MyView.sql и делаешь обычный select ... from "MyView.sql" group by ... order by ...
О-ля-ля! (с) "Назад в будущее"


evvcom   (2005-11-28 15:52:00) [5]


> msguns ©   (28.11.05 15:25) [6]

А Cast тут где? Такой набор получается из [2] 2. внутренних селектов объединенных union. Остается сделать еще один select из этого результата и получится, что надо.
Могу предложить:
1. То что уже предложил > mr.il ©   (28.11.05 15:36) [7]
2. Добавить туда еще order by "Date" и перегнать в TClientDataSet, выполнив группировку уже на клиенте.
3. Создать дополнительную таблицу. В нее скидывать INSERT-ом этот SELECT. Потом результирующий select из этой промежуточной таблицы.


NILLO   (2005-11-28 15:46:00) [6]

Самое лучшее к чему я пришел это испольование подзапроса.


mr.il   (2005-11-28 15:36:00) [7]

А есче перейти на клиент-сервер и там в СП делать че хош.


msguns   (2005-11-28 15:25:00) [8]

Можно получить вот такой НД:

Date          |  Count < 50 | Count >50 но <100 | Count >=100
18.10.2005  |156            | 0                         | 0
19.10.2005  | 11             | 0                         | 0
18.10.2005  |0               | 100                      | 0
19.10.2005  |0               | 111                      | 0
18.10.2005  |0               | 0                         | 256
19.10.2005  |0               | 0                         | 122

Через Cast + Group By + Union


NILLO   (2005-11-28 14:51:00) [9]

Ну как, мне уже можно отчаиваться и впадать в панику?


Sergey13   (2005-11-28 14:37:00) [10]

2[2] evvcom ©   (28.11.05 14:17)
Согласен. Поторопился я.


NILLO   (2005-11-28 14:25:00) [11]

Теоретически это должно работать, я согласен, но на практике прога вешается и причем вешается на смерть. Я думаю, что это из-за большого объема базы там порядка 50 000 записей.


evvcom   (2005-11-28 14:17:00) [12]


> Sergey13 ©   (28.11.05 13:28) [1]

Низя так джойнить. Допустим P.PlayedRub< 50 удовлетворяют 5 записей, а AND P1.PlayedRub BETWEEN 50 AND 100 - 10 записей. В результате джойна получим 50 записей.

> NILLO

Навскидку вижу 3 способа, но с LocalSQL ни один не прокатит:
1. самый оптимальный:
select
 Sum(case when PlayedRub<50 then 1 else 0) as interval1,
 Sum(case when PlayedRub BETWEEN 50 AND 100 then 1 else 0) as interval2
from ...

2.
select sum(i1) as i1, sum(i2) as i2
from (
 select count(*) as i1, 0 as i2 from ... where PlayedRub<50
 union
 select 0 as i1, count(*) as i2 from ... where PlayedRub BETWEEN 50 AND 100)

3.
select t1."Date", t1.i1, t2.i2
from (select "Date", count(*) as i1 from ... where PlayedRub<50 group by "Date") t1
 full join
   (select "Date", count(*) as i2 from ... where PlayedRub BETWEEN 50 AND 100 group by "Date") t2


Sergey13   (2005-11-28 13:28:00) [13]

Попробуй примерно так
SELECT S.CashNumber, S."Date", COUNT (P.PayedRub)
FROM CashSail S, CashPay P, CashPay P1, CashPay P2
WHERE (P.ZNumber = S.Znumber)
AND (P1.ZNumber = S.Znumber)
AND (P2.ZNumber = S.Znumber)
AND P.PlayedRub< 50
AND P1.PlayedRub BETWEEN 50 AND 100
AND P2.PlayedRub>100
AND (P.CheckNumber = S.CheckNumber)
AND (P1.CheckNumber = S.CheckNumber)
AND (P2.CheckNumber = S.CheckNumber)
AND (S."Date" BETWEEN ‘18.10.2005’ AND ‘19.10.2005’)
GROUP BY S.CashNumber, S."Date";


Наверх

Титульная страница Поиск, карта сайта Написать письмо