Linux за българи: Форуми

Програмиране => Общ форум => Темата е започната от: laskov в Feb 22, 2017, 16:54



Титла: SQL. SQLite3. Сбор на стойности, някои от които са NULL
Публикувано от: laskov в Feb 22, 2017, 16:54
Имам таблица
CREATE TABLE Tablica(ID integer primary key, DateD Date not null, a Decimal(2,1), b Decimal(2,1), c Decimal(2,1));
Искам
SELECT ID, DateD, a, b, c, a+b+c AS Suma FROM Tablica;

но не навсякъде има стойности в a, b и с. Там, където и трите имат стойности е ОК, но ако някое от тях е NULL, Suma е NULL, а на мен това не ми харесва. Искам ако някое е NULL да се третира като 0.
Благодаря предварително за помощта!


Титла: Re: SQL. SQLite3. Сбор на стойности, някои от които са NULL
Публикувано от: ieti в Feb 22, 2017, 17:59
Понеже няма NVL предполагам с CASE ще стане...

CASE WHEN fieldname IS NULL THEN 0 ELSE fieldname END

Като гледам може и ifnull да стане също.

ifnull(X,Y)

The ifnull() function returns a copy of its first non-NULL argument, or NULL if both arguments are NULL. Ifnull() must have exactly 2 arguments. The ifnull() function is equivalent to coalesce() with two arguments.

sqlite> SELECT ifnull(null, 6);
Result:  6

От там би трябвало да е нещо такова..

select ifnull(a,0) + ifnull(b,0) + ifnull(c,0) from tablica;



Титла: Re: SQL. SQLite3. Сбор на стойности, някои от които са NULL
Публикувано от: laskov в Feb 23, 2017, 11:13
От там би трябвало да е нещо такова..

select ifnull(a,0) + ifnull(b,0) + ifnull(c,0) from tablica;
Сърдечно благодаря!
Работи, само дето "закръглянето" на числото, което се получава ме изненада :)
round(x) работи, но round(x,y) - не


Титла: Re: SQL. SQLite3. Сбор на стойности, някои от които са NULL
Публикувано от: remotexx в Feb 23, 2017, 20:59
Колегата май без да иска те е подвел - прочети малко за Type Affinity от официалната документация ($2)
според мен би трябвало да е (щом са ти REAL числата)
Код
GeSHi (SQL):
  1. SELECT IFNULL(a,0.0) + IFNULL(b,0.0) + IFNULL(c,0.0) AS Total FROM Table1;
  2.  

иначе със старото ще е непредсказуемо - напр.
(зависи дали израза се оценява от ляво на дясно или обратно но се прави имлицитно конвертиране на типовете и понеже 0 - INT от един момент нататъка ти ги закръглява към INT а на тебе типа ти е DECIMAL(2,1) т.е. реално е REAL понеже 'Each value stored in an SQLite database (or manipulated by the database engine) has one of the following storage classes: NULL, INTEGER, REAL, TEXT, BLOB ')

 ако първото е NULL т.е. 0 то и другите 2 ще се конверитат до INT - 0 + 1.1 + 2.2 = 0+1+2=3
 ако второто е NULL т.е. 0 то и другото 1 ще се конверита до INT - 1.1 + 0 + 2.2 = 1.1+0+2=3.1
 ако третото е NULL т.е. 0 то само то ще се конверитат до INT - 1.1 + 2.2 + 0 = 3.3


Титла: Re: SQL. SQLite3. Сбор на стойности, някои от които са NULL
Публикувано от: laskov в Feb 24, 2017, 12:25
Проблемът със закръглянето може би ще се окаже, че е създаден от средата за програмиране - Lazarus. Експериментите в командния интерпретатор на SQLite3 дават един и същ и винаги верен резултат и от двата варианта с ifnull като не се налага ползване на round.
Така че, сигурно ще се окаже, че round(x,y) си работи и неправилно съм го набедил :) , но не ми се експериментира повече засега.
Основният ми проблем е решен. Сега имам друг с параметрите на TSQLQuery :) edit: , който пък реших като се отказах от ползването им :)
Благодаря за идеите!


Титла: Re: SQL. SQLite3. Сбор на стойности, някои от които са NULL
Публикувано от: remotexx в Feb 24, 2017, 20:32
Е па що Лазарус? Защо не Qt4 или 5 напр.? -хем с C++ хем може да се подкара на почти всичко - Уин/Лин/Мак даже и за вграждане, IоT и пр.

т.е. предполага се че щом това си избрал, поне него поназнайваш?!
единствения 'проблем' при начинаещите е - как да се подаде NULL
ама то с това на всеки език се сблъскваш - аз наскоро на C# се борих със това нещо (и решениет същото като на Delphi /предполагам и при Лазарус е същото - ама то това се очква след като пред големия провал на .Net 1.x за 2.0 Майкрософт наеха инженерите от Delphi да им го направвят т.е. напазаруваха си ги де демемк всичко е легално  ;D )

между другото ако няма (или трудно се намира) помощ  оналйн за Лазарус - търси за същото нещо но напр. на Делфи/Delphi, като за предпочитане стара версия

...та какъв е проблема с праметрите?

Не се подвеждай че Sqlite типа е REAL - Object Pascal Real е наполовина на Double (който всъщност искаш да ползваш) понеже па Decimal може много малко аритметика да правиш с него ама инак с unlimited precision  :D
т.е. ако си го представил тоя Sqlite Decimal като Real в Паскал е нормално да има закръгляване, то даже и при Double ще има закръгляване ама загубите са пренебрежимо малки т.е. (теоретично) ако си го направиш REAL / Sqlite <-> Double/Pascal би трябвало да ти се получи еднакво (закръгляване)
между другото Паскала има и още по-голям тип Extended - за още по-големи числа но не е с по-голяма прецизност
...тъй като гледам за тебе с точност до 2-4 знака след запетайката е най-добре Currency да ползваш

защото инак - Decimal - 0.1 е точно число ама в двойчна бр. система е безкрайна периодична дроб и винаги ще ти е закръглено
http://www.exploringbinary.com/why-0-point-1-does-not-exist-in-floating-point/


Титла: Re: SQL. SQLite3. Сбор на стойности, някои от които са NULL
Публикувано от: go_fire в Feb 24, 2017, 23:43
Или както би казал Stilgar:

Андерс! Да се свети името му  ;D

Не, че има нещо общо с темата…


Титла: Re: SQL. SQLite3. Сбор на стойности, някои от които са NULL
Публикувано от: growchie в Feb 25, 2017, 20:24
Qt си имат перфектна абстракция точно за работа с бази данни. Там всичките типове се претакат през QVariant и няма проблеми при конвертирането.