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

Вниз

SUM -> NULL   Найти похожие ветки 

 
PKT   (2002-12-26 04:59) [0]

Запрос:
select SUM(CREDIT) - SUM(DEBET) from ...
Если у всех записей, например, поле DEBET пустое,
то на выходе вместо суммы CREDIT минус нуль возвращается
пустое значение.

Сейчас делаю отдельно запрос SUM(CREDIT), отдельно
SUM(DEBET), проверяю их на if not NULL и нахожу разницу.

А можно ли все-таки одним запросом ?


 
ЮЮ ©   (2002-12-26 06:57) [1]

Низзя


 
REP ©   (2002-12-26 07:16) [2]

Замени в поле DEBET все значения с NULL на 0. В SQL, если попадается значение NULL в поле, то выражение тоже с ним возвращает NULL. NULL это не 0.


 
PKT   (2002-12-26 07:58) [3]

to: ЮЮ © (26.12.02 06:57)
Спасибо за однозначный ответ, ну тогда оставлю как есть.


 
-=Sergeante=- ©   (2002-12-26 09:30) [4]

Чесно говоря, мне тоже не понятна логика такого поведения...
Если из числа вычитаем "пусто", то очевидно и остаться какое-то число, но никак не "пусто".
Сколько раз уже натыкался на эту фичу, столько же раз недоумевал от такого поведения. А оборачивается это лишним кодингом проверок и сравниваний с NULL значениями и заменой оных на 0.
Бред. Если это не бред, то ткните меня носом в чём я не прав.


 
Alexandr ©   (2002-12-26 09:33) [5]

null это не ноль. это НЕИЗВЕСТНО.
пример
2+х.з. сколько
чему равно? х.з. сколько.

В чем проблема?
Сначала навтыкаете null куда надо и ненадо, а потом думаете, что у вас null неправильно работает.
Вы его просто готовить не умеете. А коли не умеете, то и используйте лучше. Пока не поймете в нем необходимость.


 
neXt ©   (2002-12-26 09:39) [6]

а в MSSQL можно:
select isnull(SUM(CREDIT),0) - isnull(SUM(DEBET),0) from ...


 
Johnmen ©   (2002-12-26 09:44) [7]

>-=Sergeante=- © (26.12.02 09:30)

Ты неправ ! Сушествует четкая и одназначная логика работы со значениями полей, в т.ч. и с NULL ("неопределенность"). см. Alexandr © (26.12.02 09:33).
От себя добавлю, что если поле предполагает над собой какие-то действия, то и значение его должно быть определено. А если ты его не определил - наличие провалов при проектировании БД.


 
Anatoly Podgoretsky ©   (2002-12-26 09:50) [8]

В данный момент надо сделать преаобразование полей из NULL и реструктиризация таблицы после этого, наложить ограничение, что бы больше такого не повторялось.


 
Sergey13 ©   (2002-12-26 09:50) [9]

2-=Sergeante=- © (26.12.02 09:30)
>Если из числа вычитаем "пусто"...
NULL - это не "пусто", это именно х.з. сколько. 8-) И этим надо уметь пользоваться при проектировании базы. Например это незаменимо во всякого рода ID-шниках, где установить 0 (нуль) нельзя по правилам ссылочной целостности. А вот для вещественных атрибутов (цены, количества и т.д) нужно выставлять дефолтные значения для полей (0 например), тогда и проблем не будет. И производительность вырастет (часто).


 
myor ©   (2002-12-26 10:24) [10]

нечего удивляться.
null<>0 и точка
null- это именно неопределенные данные (см. теорию рбд), и не нужно их использовать там, где можно (и нужно) использовать пустые данные, т. е. 0 для числовых полей и "" (пустую строку)- для строк.


 
-=Sergeante=- ©   (2002-12-26 10:39) [11]

Ну запинали. Тем не менее, что-то более-менее прояснилось. Вытираю сопли и иду читать теорию. Спасибо.


 
diMAN ©   (2002-12-26 10:53) [12]

Вот, лови, я тоже как то столкнулся с этой проблемой и вывернулся следующим образом:

select SUM(CAST(""0""||CAST(CREDIT AS CHAR(30)) AS MONEY)) - SUM(CAST(""0""||CAST(DEBET AS CHAR(30)) AS MONEY)) from ...

Работает 100%. Почему именно так, думаю объяснять не стоит, разберёшся :))


 
Anatoly Podgoretsky ©   (2002-12-26 10:54) [13]

-=Sergeante=- © (26.12.02 10:39)
По теории, может это поможет NULL <> NULL


 
Johnmen ©   (2002-12-26 11:23) [14]

>diMAN © (26.12.02 10:53)
>Работает 100%.

Где работает ?



 
Val ©   (2002-12-26 11:29) [15]

>Johnmen © (26.12.02 11:23)
Где работает ?
подозреваю, что нигде.


 
myor ©   (2002-12-26 11:33) [16]

а че это вы тут делаете, а?
автор вопроса уже давно упал с этой ветки!


 
Johnmen ©   (2002-12-26 11:38) [17]

>Val © (26.12.02 11:29)
>подозреваю, что нигде.

Вот и у меня закрались подозрения...:)))


 
MsGuns ©   (2002-12-26 11:48) [18]

В Local SQL, я думаю, работать будет.

К вопросу же о NULL. Уважая мастаков, не могу не отметить, что порою они бывают излишне категоричны. Что значит фраза

>Alexandr © (26.12.02 09:33)
Сначала навтыкаете null куда надо и ненадо, а потом думаете, что у вас null неправильно работает.
Вы его просто готовить не умеете. А коли не умеете, то и используйте лучше. Пока не поймете в нем необходимость.
?

А если база уже есть, создана n лет назад, содержит полмиллиона записей и успешно юзается m-м кол-вом персонала ?
Искусство программирования заключается не только в том, как проектировать НОВЫЕ проекты, но и как выкручиваться в старых, не так ли ?


 
Anatoly Podgoretsky ©   (2002-12-26 11:48) [19]

Да нужен он нам, нам и без него хорошо :-)


 
Lady D ©   (2002-12-26 13:28) [20]


SELECT SUM(ALL CREDIT) - SUM(ALL DEBET) from ...

Подсчитает все NOT NULL


 
-=Sergeante=- ©   (2002-12-26 15:03) [21]


> MsGuns © (26.12.02 11:48)
> А если база уже есть, создана n лет назад, содержит полмиллиона
> записей и успешно юзается m-м кол-вом персонала ?
> Искусство программирования заключается не только в том,
> как проектировать НОВЫЕ проекты, но и как выкручиваться
> в старых, не так ли ?


О! Здравая мысль.


 
petr_v_a ©   (2002-12-26 16:44) [22]

Искусство программирования - в том, чтоб не влезть в дурацкий проект :))
Честно, ничей конкретно не имел в виду :))


 
MsGuns ©   (2002-12-26 19:40) [23]

>petr_v_a © (26.12.02 16:44)
> Искусство программирования - в том, чтоб не влезть в дурацкий проект :))

Это искусство называется "дипломатией". У настоящих программеров, как правило, начисто отсутствует 8))


 
Lady D ©   (2002-12-27 09:45) [24]

Похоже опять никто не понял (или сделал вид), что я дала "короткое" и верное решение. Lady D © (26.12.02 13:28).
Включение ключей в аггрегатные функции может избавить от многих головных болей. Например, мне нужно выдать отчет по клиентам с суммой продаж и вычислением Profit по каждому. Естественно, должен быть и итог с такими же полями. Нет проблем если каждый из клиентов покупал в этот отрезок времени, а если нет? Его показатели пусты, а COUNT его посчитает. Как же быть с итогом? Очень просто: COUNT(ALL saldo) подсчитает всех, у кого сумма NOT NULL... COUNT(DISTINCT saldo) подсчитает все уникальные saldo(не знаю зачем это здесь, но тем не менее). То же самое справедливо и для SUM,AVG... Проблема в том, что написала об этом Lady и ни у кого не хватит духа сказать: да, ты права, я об этом читал, но давно забыл. Напротив, каждый здесь ждет случая (подходящего и не очень) чтобы попестовать меня. Итак, решение:

SELECT SUM( ALL credit) - SUM( ALL debit) FROM ...

Есть сегодня желающие поспорить?


 
ЮЮ ©   (2002-12-27 09:54) [25]

О чём? Подчитать то подсчитает, но если в одном стодбце нет ни одной записи со значением не NULL, то и SUMM() вернет NULL и пезультат будет NULL независимо от суммы по второму столбцу.
а SELECT SUM(ALL credit) - SUM(ALL debit) FROM ... ТОЖДЕСТВЕНЕН авторскому select SUM(CREDIT) - SUM(DEBET) from ...


 
passm ©   (2002-12-27 10:00) [26]

ЮЮ © (27.12.02 09:54)> Верно сказано насчет тождественности.
.-ALL------.
>>-SUM--(----+----------+--expression--)-----------------------><
"-DISTINCT-"


 
Johnmen ©   (2002-12-27 10:26) [27]

>Lady D © (27.12.02 09:45)

Маша, у Вас просто какая-то юношеская горячность...:)))
см. ЮЮ © (27.12.02 09:54)


 
diMAN ©   (2002-12-27 11:01) [28]

> Johnmen © (26.12.02 11:23)
> Где работает ?

> Val © (26.12.02 11:29)
> Где работает ?
> подозреваю, что нигде.

> MsGuns © (26.12.02 11:48)
> В Local SQL, я думаю, работать будет.

Вы вопрос внимательно читали
SUM -> NULL [D5, Paradox]
^^^^^^^
Естественно, что в Local SQL. И говоря что это будет 100% работать, я не лукавил, т.к. данный код у меня уже более трёх лет с успехом работает. А кто не верит - проверьте, а уже потом говорите что нигде не будет работать.


 
Johnmen ©   (2002-12-27 11:10) [29]

>diMAN © (27.12.02 11:01)

По поводу 100% :
Где выполняется запрос ? Как выполняется ? Какой движок используется ?


 
Sergey13 ©   (2002-12-27 11:42) [30]

Господа, а вам не кажется, что вы идете не тем путем. Не проще ли будет добавить в таблицы на эти поля дефолтное значение 0, и проапдейтить существующие записи
update table set debit=0 where debit is null
update table set credit=0 where credit is null

И все!!! Все будет работать правильно. Работа на 5 минут. Я бы сделал именно так.


 
petr_v_a ©   (2002-12-27 13:16) [31]

> Lady D © (27.12.02 09:45)
> Проблема в том, что написала об этом Lady...
По Вашему участию в других дискуссиях у меня, по крайней мере, сложилось впечатление, что Ваш уровень гораздо выше среднего уровня участников форума, НО: Вас опять подвело "невнимательное читание писанины" и Вы, как бы это при девушках сказать, к сожалению, лажанулсь :)
sum(all column_value) по синтаксису Local SQL эквивалентно
sum( column_value)
А девушек у нас любят, берегут, и уважают :), рискну выразить мнение подавляющего большинства участников форума :)

По сути вопроса: null в результате sum(column_value) получается, либо когда не просуммировано ни одной строки, либо когда суммируются только null`ы. Так как в Local SQL нет ф-ции типа nvl(nullable_expr,expr), которая в случае, если nullable_expr is null возвращала бы expr, в противном - ниче не трогала, прав Sergey13 © (27.12.02 11:42) - даже если Вы победите данный конкретный запрос, null`ы гадить Вам будут каждый день до скончания века


 
Anatoly Podgoretsky ©   (2002-12-27 13:26) [32]

Lady D © (27.12.02 09:45)
Есть делание - предикакт ALL является предикатом по умолчанию [ALL]


 
diMAN ©   (2002-12-30 16:46) [33]

> Johnmen © (27.12.02 11:10)
> Где выполняется запрос ? Как выполняется ? Какой движок
> используется ?

Например, в моей программе. Всегда корректно 100% (через TQuery). D5, D6 + BDE + Paradox.

Вот работающий у меня фрагмент:

Screen.Cursor := crHourGlass;
with WorkQuery do
try
SQL.Clear;
SQL.Add("SELECT A.ShortName OrgName, CAST(""0""||CAST(B.Prihod AS CHAR(30)) AS MONEY) Prihod1, ");
SQL.Add("CAST(""0""||CAST(C.Prihod AS CHAR(30)) AS MONEY) Prihod2, ");
SQL.Add("CAST(""0""||CAST(D.Vernut AS CHAR(30)) AS MONEY) Vernut1, ");
SQL.Add("CAST(""0""||CAST(E.Vernut AS CHAR(30)) AS MONEY) Vernut2, ");
SQL.Add("CAST(""0""||CAST(F.Oplata AS CHAR(30)) AS MONEY) Oplata1, ");
SQL.Add("CAST(""0""||CAST(G.Oplata AS CHAR(30)) AS MONEY) Oplata2");
SQL.Add("FROM "org.db" A LEFT OUTER JOIN "prihodbefore.db" B ON A.Code=B.OrgCode");
SQL.Add("LEFT OUTER JOIN "prihodbetween.db" C ON A.Code=C.OrgCode");
SQL.Add("LEFT OUTER JOIN "vernutbefore.db" D ON A.Code=D.OrgCode");
SQL.Add("LEFT OUTER JOIN "vernutbetween.db" E ON A.Code=E.OrgCode");
SQL.Add("LEFT OUTER JOIN "oplatabefore.db" F ON A.Code=F.OrgCode");
SQL.Add("LEFT OUTER JOIN "oplatabetween.db" G ON A.Code=G.OrgCode");
SQL.Add("WHERE A.ID=1");
SQL.Add("ORDER BY A.ShortName");
Open;
DbiMakePermanent(handle, PChar(DataBaseTDir + "postavsvod.db"), true);
Close;
except
Screen.Cursor := crDefault;
ShowMessage("Ошибка!");
end;


 
Delirium^.Tremens ©   (2002-12-30 16:50) [34]

Да, круть, нафиг. После приклейки нуля больше всего мне понравилось : LEFT OUTER JOIN. Видимо на "LEFT RIGHT OUTER INNER JOIN" BDE уже ругнулся.


 
Johnmen ©   (2002-12-30 17:39) [35]

>diMAN © (30.12.02 16:46)

То есть ты хочешь сказать, что есть поля (C.Prihod, D.Vernut, F.Oplata), в которых значение NULL ? И, кстати, каковы типы этих полей ?




 
diMAN ©   (2002-12-31 10:35) [36]

>Johnmen © (30.12.02 17:39)
> То есть ты хочешь сказать, что есть поля (C.Prihod, D.Vernut, > F.Oplata), в которых значение NULL ? И, кстати, каковы типы
> этих полей ?

Да, именно это я и хочу сказать. Все эти поля типа ftCurrency. В них находятся сведения о суммах прихода товара, возврата товара, оплаты за товар по каждой из организаций за определённый период времени (любой - хоть 1 день, хоть 1 месяц, хоть 1 год). И естественно, за данный период конкретная оргганизация могла не получать (возвращать, оплачивать) товар, т.е. значения этих полей будут NULL.

> Delirium^.Tremens © (30.12.02 16:50)
> Да, круть, нафиг. После приклейки нуля больше всего мне
> понравилось : LEFT OUTER JOIN. Видимо на "LEFT RIGHT OUTER
> INNER JOIN" BDE уже ругнулся.

Я в этом ничего страшного не вижу. Я понимаю что слово OUTER можно ставить, а можно - и нет. Но мне так удобнее и нагляднее. Я привык делать так. К тому же в Local SQL Help -> OUTER join (файл localsql.hlp) в примерах дается именно такой (полный) вариант записи SQL-запроса.


 
Johnmen ©   (2002-12-31 10:47) [37]

>diMAN © (31.12.02 10:35)

Вывод однозначен - NULL реализован как нулевое значение, а это не одно и то же ! (в данном конкретном случае)

>И естественно, за данный период конкретная оргганизация могла
>не получать (возвращать, оплачивать) товар, т.е. значения этих
>полей будут NULL.

Почему же ? Кто указывает, что NULL ?



 
diMAN ©   (2003-01-04 12:41) [38]

> Johnmen © (31.12.02 10:47)
> Почему же ? Кто указывает, что NULL ?

На это указывает то, как получаются таблицы prihodbefore.db, prihodbetween.db и т.д.


...
SQL.Clear;
SQL.Add("SELECT A.OrgCode, SUM(A.SummaWithNalog) Prihod FROM "opermain.db" A");
SQL.Add("WHERE A.CodeOper=1 AND A.DateOper < "" + DateToStr(WorkDateStart) + """);
SQL.Add("GROUP BY A.OrgCode");
Open;
DbiMakePermanent(handle, PChar(DataBaseTDir + "prihodbefore.db"), true);
Close;
SQL.Clear;
SQL.Add("SELECT A.OrgCode, SUM(A.SummaWithNalog) Prihod FROM "opermain.db" A");
SQL.Add("WHERE A.CodeOper=1 AND A.DateOper BETWEEN "" + DateToStr(WorkDateStart) + "" AND "" + DateToStr(WorkDateEnd) + """);
SQL.Add("GROUP BY A.OrgCode");
Open;
DbiMakePermanent(handle, PChar(DataBaseTDir + "prihodbetween.db"), true);
Close;
...


Таким образом мы вернулись к сути вопроса, что если в течение рабочего периода у организации не было прихода, то она не попадёт в таблицу "prihodbetween.db", а следовательно при объединении LEFT OUTER JOIN, поле C.Prihod (см. предыдущий пример) будет NULL. В чём я давно и легко убедился, открыв полученную таблицу через Database Desktop. Собственно это и побудило меня найти способ преобразования в SQL-запросе значения NULL в 0, что и было успешно достигнуто. Рабочий вариант запроса я и предложил автору вопроса.

P.S. Только что я создал таблицу с полями Code: ftAutoinc, Summa: ftMoney и добавил в неё пять записей, у которых поле Summa содержит NULL. Выполнил запрос SELECT SUM(Summa) FROM test, получив в результате NULL и выполнил запрос SELECT SUM(CAST("0"||CAST(Summa AS CHAR(30)) AS MONEY)) FROM test, получив в рузультате 0. Если Вы и на этот раз сомневаетесь, то проверьте собственноручно.



 
Johnmen ©   (2003-01-04 12:56) [39]

>diMAN © (04.01.03 12:41)

Последние уточнения по поводу P.S. :
Где, при помощи чего создана таблица ?
Где, при помощи чего выполнен запрос ?
Где, при помощи чего видны результаты ?


 
diMAN ©   (2003-01-04 17:09) [40]

> Johnmen © (04.01.03 12:56)
> Последние уточнения по поводу P.S. :
> Где, при помощи чего создана таблица ?
> Где, при помощи чего выполнен запрос ?
> Где, при помощи чего видны результаты ?

Все действия сделаны при помощи Database Desktop (таблица Paradox).



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

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

Наверх




Память: 0.59 MB
Время: 0.017 c
14-72473
ihtiandr
2003-01-05 15:02
2003.01.23
QReport


3-72085
Yrtimd
2002-12-28 21:36
2003.01.23
как в SQL-запросе задать условие отбора формата


1-72363
WCM
2003-01-12 13:27
2003.01.23
Length function


3-72141
novill
2002-12-30 16:01
2003.01.23
Мастаки, как QRCompositeReport просмотреть через QRPreview?


1-72336
Schummi
2003-01-02 14:36
2003.01.23
TChart в два ряда