Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.07.25;
Скачать: CL | DM;

Вниз

SQL-запрос   Найти похожие ветки 

 
ligor   (2004-07-01 16:03) [0]

Добрый день Мастера Delphi
Подскажите можно ли в запросе подсчитать сумму,
если приход помечен "П", а расход "Р"
Пример
Id Summ  KodPl
1  10    П
2  20    П
3  15    Р
4  8     П
5  22    Р


 
Соловьев ©   (2004-07-01 16:07) [1]

select (select sum(summ) from table where KodPl="П")-(select sum(summ) from table where KodPl="Р") as Summ
from table


 
Sandman25 ©   (2004-07-01 16:08) [2]

[1] Соловьев ©   (01.07.04 16:07)

... from tableWithOneRow


 
Соловьев ©   (2004-07-01 16:10) [3]

мож так?
select (select sum(summ) from table where KodPl="П")-(select sum(summ) from table where KodPl="Р") as Summ
from table
where KodPl = "@@@@"


 
Sandman25 ©   (2004-07-01 16:12) [4]

[3] Соловьев ©   (01.07.04 16:10)

Результат будет null, если "главный" where ничего не нашел.


 
ligor   (2004-07-01 16:14) [5]

Спасибо за направление
Когда подскажут думается
ну почему сам недодумался!!!


 
Соловьев ©   (2004-07-01 16:22) [6]

select max(id),(select sum(summ) from table where KodPl="П")-(select sum(summ) from table where KodPl="Р") as Summ
from table

:)


 
Sandman25 ©   (2004-07-01 16:25) [7]

:)

Вот до чего доводит отсутствие case :(


 
Fay ©   (2004-07-01 16:28) [8]

2Sandman25 ©   (01.07.04 16:25) [7]

> Вот до чего доводит отсутствие case :(

...который есть в FB15


 
Sandman25 ©   (2004-07-01 16:28) [9]

[8] Fay ©   (01.07.04 16:28)

или iif, который вроде бы есть в IB7


 
Соловьев ©   (2004-07-01 16:32) [10]

А ,че, работать будет шустренько если индексы будут :)
А с casae разве быстрее будет?


 
Соловьев ©   (2004-07-01 16:33) [11]

не-а, хотя тут индексы не нужны:)


 
Sandman25 ©   (2004-07-01 16:34) [12]

[10] Соловьев ©   (01.07.04 16:32)

Индексы по полю с 2 возможными значениями только вредят, поэтому в лучшем случае будет полное сканирование таблицы.
При использовании case каждая запись будет считываться только 1 раз.


 
Соловьев ©   (2004-07-01 16:39) [13]

интересно а как с case?


 
Sandman25 ©   (2004-07-01 16:42) [14]

С case будет один проход по таблице.
Без case будет 2 прохода, по одному для каждого из запросов вида select sum


 
Соловьев ©   (2004-07-01 16:44) [15]


> [14] Sandman25 ©   (01.07.04 16:42)

та нет, запрос:)


 
ligor   (2004-07-01 16:45) [16]

Уважаемые мастера спасибо
Запрос по времени не критичен
База чужая
У меня обычно приход с плюсом, расход с минусом
Sum считает великолепно
Здесь же время от времени нужно посчитать итоги
Почему пердидущий разработчик выбрал такой способ я незнаю
Сейчас проблема решена так
в процедуре считаем sum расход потом sum приход
потом вычитаем одно из другого,
но пока не посмотрел на запрос г. Соловьева не доходило :-))


 
Sandman25 ©   (2004-07-01 16:46) [17]

select sum(case kodpl when "П" then Summ else -Summ end)
from table


 
Соловьев ©   (2004-07-01 16:50) [18]


>  [17] Sandman25 ©   (01.07.04 16:46)

прикольно :)


 
Sandman25 ©   (2004-07-01 16:54) [19]

Есть еще другой синтаксис case:
select sum(case when when kodpl="П" then Summ else -Summ end)
from table
но в данном случае работает и первый (более эффективный в общем случае наличия >2 вариантов)


 
ligor   (2004-07-01 16:55) [20]

[17] Sandman25 ©   (01.07.04 16:46)

прикольно :)
конечно прикольно только в IB6.Х
нет case
зато есть ХП(процедуры)
которые могут возвращать набор данных
при этом описать логику возвращаемых данных
на мой взгляд легче
чем в SQL запросе на 40 строчек:-))


 
Sandman25 ©   (2004-07-01 16:56) [21]

[20] ligor   (01.07.04 16:55)

Описать логику может быть и проще, а работать может будет и медленнее. Все зависит от запроса и от текста SPL, на который этот запрос заменяется.


 
ligor   (2004-07-01 16:59) [22]

Согласен на все сто
Но ассемблер тоже быстрее
а большенство выбирают Delphi(мне так кажется)


 
Sandman25 ©   (2004-07-01 17:04) [23]

[22] ligor   (01.07.04 16:59)

Вы считаете, что

select sum(case kodpl when "П" then Summ else -Summ end)
from table

менее понятно, чем

let summa = 0;
select sum(Summ)
 into SumPrih
 from table
 where CodPl="П";
if SumPrih is not null then
 let summa = summa + sumPrih;
end if;
select sum(Summ)
 into SumRash
 from table
 where CodPl="Р";
if SumRash is not null then
 let summa = summa - sumrash;
end if;
suspend;

?


 
ligor   (2004-07-01 17:08) [24]

Убедили
Следующию разработку по возможности начну на FB15
а эту придется так домучивать
Спасибо


 
Fay ©   (2004-07-01 17:26) [25]

2ligor   (01.07.04 17:08) [24]
Что мешает домучивать на FB?


 
ligor   (2004-07-01 17:32) [26]

Пробовал по рекомедациям
перевести базу на FB1.5
все заглючело и перестало работать
(скорее всего глючу сам, опыт работы очень маленький ну очень)
Пробавал ставить этот сервер дома все пршло успешно
а вот на работе где много уже работающих программ не
получается :-((((


 
Fay ©   (2004-07-01 18:34) [27]

Быват


 
Deniz ©   (2004-07-02 08:43) [28]

> Sandman25 ©   (01.07.04 17:04) [23]
Ну уж процедуру то надо по другому писать :-(
summa = 0;
for select summ, KodPl from table into :tmpSumm, :tmpKod do begin
 if (not (tmpSumm = null)) then begin
   if (tmpKod = "Р") then tmpSumm = -tmpSumm;
   summa = summa + tmpSumm;
 end
end
suspend;

Тоже достаточно наглядно и один проход.


 
Sandman25 ©   (2004-07-02 09:09) [29]

[28] Deniz ©   (02.07.04 08:43)

Что один проход - принимается.
Что тоже достаточно наглядно - отнюдь.


 
Johnmen ©   (2004-07-02 09:11) [30]

>Deniz ©   (02.07.04 08:43) [28]
>if (not (tmpSumm = null)) then begin

if (not tmpSumm is null) then begin
:)


 
Sandman25 ©   (2004-07-02 09:16) [31]

[30] Johnmen ©   (02.07.04 09:11)
if (tmpSumm <> 0) then begin

:)


 
Соловьев ©   (2004-07-02 09:23) [32]


> Пробовал по рекомедациям
> перевести базу на FB1.5
> все заглючело и перестало работать
> (скорее всего глючу сам, опыт работы очень маленький ну
> очень)
> Пробавал ставить этот сервер дома все пршло успешно
> а вот на работе где много уже работающих программ не
> получается :-((((

я переводил свои БД с ИБ на ФБ - бекап/ресторе только делал. И все работает. А какие траблы , какие глюки возникли?


 
Johnmen ©   (2004-07-02 09:27) [33]

>Sandman25 ©   (02.07.04 09:16) [31]

Я о другом...:)


 
Sandman25 ©   (2004-07-02 09:31) [34]

[33] Johnmen ©   (02.07.04 09:27)

О том, что = не работает с null? Тогда извиняюсь :)


 
Deniz ©   (2004-07-02 12:00) [35]

> Johnmen ©   (02.07.04 09:11) [30]
Опечатка вышла, с кем не бывает ;-) но ведь в процедуре Sandman25 ©   (01.07.04 17:04) [23] их(опечаток) намного больше.
> Соловьев ©   (02.07.04 09:23) [32]
Добавлю что в некоторых случаях с IB6.x на FB1.5 даже можно просто скопировать базу.


 
Sandman25 ©   (2004-07-02 12:03) [36]

[35] Deniz ©   (02.07.04 12:00)

Каких еще опечаток? Это был синтаксис ХП на моем собственном языке моей собственной СУБД, я с IB много лет не работал :)


 
Курдль ©   (2004-07-02 12:11) [37]

Это был синтаксис ХП на моем собственном языке моей собственной СУБД

Если уж дело дошло до предложений о смене СУБД, вот 2 варианта на выбор:

select sum(decode KodPl = "П", Summ, 0) - sum(decode KodPl = "P", Summ, 0) from Table_1
или
select sum(if KodPl = "П" then Summ else 0 endif) - sum(if KodPl = "P" then Summ else 0 endif) from Table_1


 
Sandman25 ©   (2004-07-02 12:17) [38]

[37] Курдль ©   (02.07.04 12:11)

В обоих случаях KodPl будет анализироваться дважды. Сравните с [17]


 
Johnmen ©   (2004-07-02 12:19) [39]

>Sandman25 ©   (02.07.04 12:17) [38]

Зато застрахованы от чешуи типа KodPl = "О"
:)


 
Sandman25 ©   (2004-07-02 12:23) [40]

[39] Johnmen ©   (02.07.04 12:19)

А кто мешает написать
select sum(case kodpl when "П" then Summ when "Р" -Summ  else 0 end)
from table

Просто [17] работает быстрее, а если мы имеем check(kodPl in "П", "Р"), то 100% надежно.


 
Johnmen ©   (2004-07-02 12:26) [41]

>Sandman25 ©   (02.07.04 12:23) [40]
>А кто мешает написать...

А это уже "KodPl будет анализироваться дважды"
:)

>Просто [17] работает быстрее

Разумно ли экономить на спичках в данном случае ?


 
Курдль ©   (2004-07-02 12:27) [42]


> Sandman25 ©   (02.07.04 12:23) [40]
> [39] Johnmen ©   (02.07.04 12:19)
>
> А кто мешает написать
> select sum(case kodpl when "П" then Summ when "Р" -Summ
>  else 0 end)
> from table

АднАзнАчнА!!! Просто лень было подумать :) Но ведь насколько лучше, чем варивнты с ХП, ХЗ и ТП?!


 
Sandman25 ©   (2004-07-02 12:30) [43]

ср.
if FieldByName("kodPl").AsInteger = 1 then
 ...
// без else!
if FieldByName("kodPl").AsInteger = 2 then
 ..

и
case FieldByName("kodPl").AsInteger of
 1: ...
 2: ...

во втором случае анализируется либо 1 либо 2 раза, причем нет второго обращения к DataSet. Даже если оптимизатор заменяет первый случай на
LocalVar := FieldByName("kodPl").AsInteger;
if LocalVar = 1 then
 ...
// без else!
if LocalVar = 2 then

все равно имеем проигрыш из-за того, что сравнений в среднем 2, а не 1.5 как в моем варианте :)


 
Danilka ©   (2004-07-02 12:40) [44]

как не самый лучший вариант, чтобы не учитывать "О":

select sum(case when when kodpl="П" then Summ else -Summ end)
from table t1
where exists (select 1 from table where id = t1.id and kodpl in ("П", "Р"))

:))


 
Соловьев ©   (2004-07-02 12:43) [45]


> чтобы не учитывать "О":

select sum(case when when kodpl="П" then Summ where kodpl="Р" then -Summ end)
from table


 
Соловьев ©   (2004-07-02 12:47) [46]

Вот так правильно:
select sum(case kodpl when "П" then Summ when "Р" then Summ -Summ end)
from table



Страницы: 1 2 вся ветка

Текущий архив: 2004.07.25;
Скачать: CL | DM;

Наверх




Память: 0.58 MB
Время: 0.044 c
1-1089688636
ksa2002
2004-07-13 07:17
2004.07.25
Qreport


1-1089358713
Billi
2004-07-09 11:38
2004.07.25
File Access denied


1-1089368180
Alek
2004-07-09 14:16
2004.07.25
Парсинг стринга


3-1088626619
3APA3A
2004-07-01 00:16
2004.07.25
Как узнать VARCHAR длину


3-1088651692
Ozone
2004-07-01 07:14
2004.07.25
"Удобное" хранение данных