Форум: "Базы";
Текущий архив: 2004.07.25;
Скачать: [xml.tar.bz2];
Вниз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 beginif (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;
Скачать: [xml.tar.bz2];
Память: 0.55 MB
Время: 0.035 c