mysql =?ISO-8859-2?Q?=B3=B1czenie?= udf
abe - 21-03-2007 00:04
mysql =?ISO-8859-2?Q?=B3=B1czenie?= udf
Witam
Czy ktos moglby mnie naporowadzic gdzie szukac bledu. Stworzylem w C++ agregujaca funkcje urzytkownika liczaca srednia - ktora nie bierze pod uwage zer. Gdy uzywam ta funkcje samodzielnie wyniki sa poprawne natomiast gdy chce do niej cos dodac (np: pomnozyc przez zmienna), wtedy daje nieprzewidziane wyniki.
--nie dziala SELECT ( srednia_bez_zer(kol1)*2 + srednia_bez_zer(kol2)*3 )/(2+3) AS srednia_wazona FROM dane;
--dziala SELECT ( k.kol1*2 + k.kol2*3 )/(2+3) AS srednia_wazona FROM ( SELECT srednia_bez_zer(kol1) AS kol1, srednia_bez_zer(kol2) AS kol2 FROM dane ) AS k;
W razie czego wkleje kody funkcji ale poki co nie bede zaciemnial postu bo chodzi mi glownie o zrozumienie dlaczego pierwszy sposob nie dziala mimo ze drugi wykonuje sie poprawnie Pozdrawiam.
Maciek Dobrzanski - 22-03-2007 00:05
"abe" <abe@o2.pl> wrote in message news:etpslu$djd$1@nemesis.news.tpi.pl...
> natomiast gdy chce do niej cos dodac (np: pomnozyc przez zmienna), wtedy > daje nieprzewidziane wyniki.
Swego czasu były bugi zwązane z agregującymi UDFami, których wyniki używane były w liście SELECT do dalszego przetwarzania. Poszukaj na bugs.mysql.com. Może Twoja wersja jest podatna na te błędy, a w nowszych zostało to poprawione.
Maciek
Rafal \(sxat\) - 22-03-2007 00:06
sprawdz to:
avg(cast(<komorka> as signed integer)) lub cast(avg(<komorka>) as signed integer))
pozdrawiam Rafal sxat
abe - 22-03-2007 00:06
Maciek Dobrzanski wrote:
> Swego czasu były bugi zwązane z agregującymi UDFami, których wyniki > używane były w liście SELECT do dalszego przetwarzania. Poszukaj na > bugs.mysql.com. Może Twoja wersja jest podatna na te błędy, a w nowszych > zostało to poprawione.
Faktycznie bug był zgłaszany jednak nie mogę doszukać się czy zosał on naprawiony a jeśli tak to od której wersji. Mysql którego używam to 5.0.24a - wiec stosunkowo nowy. Pozatym stawiam, że większe są szanse, iż to ja cos skopałem.
W praktyce wyglada to tak jak by nie była dokonywana agregacja
struct Buffer { long long count; long long value; }
double srednia_bez_zer( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char* is_error ) {
Buffer* buffer = (Buffer*)initid->ptr; if( buffer->count == 0 ) //i wlasnie to -1 jest zwracane //(tyle razy ile jest wiekszy w tabeli) //jak w select dodajemy cos do tej funcji return -1.0;
return buffer->value / (double)(buffer->count) }
Oczywiscie pozstałe funkcje (srednia_bez_zer_init, itd) sa zaimplementowane
Pozdrawiam
abe - 22-03-2007 00:06
sxat\ wrote:
> sprawdz to: > > avg(cast(<komorka> as signed integer)) > lub > cast(avg(<komorka>) as signed integer)) >
Niestety rzutowanie nie wnosi nic nowego :/. Walcze dalej
Pozdrawiam
Rafal \(sxat\) - 22-03-2007 00:06
> Niestety rzutowanie nie wnosi nic nowego :/. Walcze dalej
pokaz dane (jako dump tabelki)
i jaki chcesz osiagnac wynik bo az mnie ciarki przechodza jestli ten silnik cos knoci.....
Maciek Dobrzanski - 23-03-2007 00:02
In news:ets0k0$gnp$1@nemesis.news.tpi.pl, abe <abe@o2.pl> wrote:
> Oczywiscie pozstałe funkcje (srednia_bez_zer_init, itd) sa > zaimplementowane
To pokaż jeszcze funkcje _clean (_clear?) i _add.
Maciek
abe - 23-03-2007 00:02
> To pokaż jeszcze funkcje _clean (_clear?) i _add.
Miło by było, aby w poniższym kodzie był błąd bo jakoś nie chce mi się wierzyć, że mysql zle obsługuje udf.
#include <my_global.h> #include <my_sys.h> #include <mysql.h> #include <m_ctype.h> #include <m_string.h>
extern "C" { my_bool srednia_bez_zer_init( UDF_INIT* initid, UDF_ARGS* args, char* message );
void srednia_bez_zer_deinit( UDF_INIT* initid );
void srednia_bez_zer_reset( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char *error );
void srednia_bez_zer_clear( UDF_INIT* initid, char* is_null, char *error );
void srednia_bez_zer_add( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char *error );
double srednia_bez_zer( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char *error ); }
struct Buffer { long long count; long long value; };
my_bool srednia_bez_zer_init( UDF_INIT* initid, UDF_ARGS* args, char* message ) { if (args->arg_count != 1) { strcpy(message,"wrong number of arguments"); return 1; }
if (args->arg_type[0] != INT_RESULT) { strcpy(message,"srednia_bez_zer() requires a int as parameter 1"); return 1; }
Buffer *buffer = new Buffer; buffer->count = 0; buffer->value = 0;
initid->decimals = 4; initid->maybe_null = 0; initid->ptr = (char*)buffer;
return 0; }
void srednia_bez_zer_deinit( UDF_INIT* initid ) { delete initid->ptr; }
void srednia_bez_zer_reset( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char* is_error ) { srednia_bez_zer_clear( initid, is_null, is_error ); srednia_bez_zer_add( initid, args, is_null, is_error ); }
void srednia_bez_zer_clear( UDF_INIT* initid, char* is_null, char* is_error ) { Buffer *buffer = (Buffer*)initid->ptr; buffer->count = 0; buffer->value = 0; *is_null = 0; *is_error = 0; }
void srednia_bez_zer_add( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char* is_error ) { if (args->args[0]==NULL) return;
if(*((long long*)args->args[0])==0) return;
Buffer *buffer = (Buffer*)initid->ptr; buffer->value += *((long long*)args->args[0]); buffer->count++; }
double srednia_bez_zer( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char* is_error ) { Buffer* buffer = (Buffer*)initid->ptr;
if (buffer->count==0) return 0.0;
return buffer->value / (double)(buffer->count); }
abe - 23-03-2007 00:02
> pokaz dane (jako dump tabelki) > CREATE TABLE `ocena_kol_2007z` ( `id` int(11) NOT NULL auto_increment, `id_op` int(11) NOT NULL, `uwagi` text NOT NULL, `kol1` tinyint(1) NOT NULL, `kol2` tinyint(1) NOT NULL, `kol3` tinyint(1) NOT NULL, `kol4` tinyint(1) NOT NULL, `kol5` tinyint(1) NOT NULL, `kol6` tinyint(1) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM AUTO_INCREMENT=2394 DEFAULT CHARSET=latin1;
INSERT INTO `ocena_kol_2007z` VALUES (1,17,'',5,5,5,5,3,5) itd
> i jaki chcesz osiagnac wynik bo az mnie ciarki przechodza jestli ten > silnik cos knoci.....
Wynik to obliczenie średniej ważonej z kolumn od kol1 do kol6 (i oczywiscie z wag wprowadzanych juz w zapytaniu) gdzie wartości 0 nie będą brane pod uwagę.
Ale nie o wynik tutaj chodzi, ani tym bardziej o dane bo funkcja ma działać dla każdych danych. Chodzi o zastosowanie własnej funkcji agregujacej, której nie mogę wporst mnożyć przez wagę i sumować z kolejną funkcją bo taka konstrukcja nie działa.
Moge natomiast obudować tą funkcję podzapytaniem i dopiero wynik podzapytania mnożyć przez wagi i dalej sumować - tak jak pokazalem w pierwszym poscie.
Pytanie brzmi dlaczego pierwsza konstrukcja nie działa mimo że druga śmiga aż miło.
Pozdrawiam
Rafal sxat - 24-03-2007 00:01
=?iso-8859-2?Q?Re:_mysql_=B3=B1czenie_udf?=
> z wag wprowadzanych juz w zapytaniu) gdzie wartości 0 nie będą brane pod > uwagę.
aby wartosc zero ma nie byc brana pod uwage aby przy funkcjach AVG nie byla brana wartosc zero pod uwage musisz ja zamienic na null AVG(0+0+2+0)=>,5 AVG(IF(komorka=0,NULL,komorka))=> tj IF(komorka=0,NULL,komorka)
a z tamtym sie dzisiaj pobawie :)
pozdrawiam Rafal
-- Archiwum grupy: http://niusy.onet.pl/pl.comp.bazy-danych
zanotowane.pldoc.pisz.plpdf.pisz.pleffulla.pev.pl
|
Gdzie MySQL 4.1, a gdzie 5.0?
[MS SQL] "set names" (mySQL) w MS SQL
oracle -> oracle lub oracle -> mysql replikacja - programy
[mysql 4.0] SELECT t1.id, t1.foo FROM t1 oraz COUNT t2 w jednym zapytaniu.
[MySQL] Zwrot tego, co pasuje i nie pasuje :-/
[pgsql] Dostosowanie składni MySQL 5.0 -> PGSQL 8.1
[mysql] galeria zdjec - numerowanie zdjec
[MySQL] Zapytanie z pliku , wynik do pliku
[mysql] CONCAT agregujący, ale nie GROUP_CONCAT()
mysql data 0000-00-00 na koniec
zanotowane.pldoc.pisz.plpdf.pisz.pllunadance.htw.pl
Cytat
Decede mihi sole - nie zasłaniaj mi słonca. Gdy kogoś kochasz, jesteś jak stworzyciel świata - na cokolwiek spojrzysz, nabiera to kształtu, wypełnia się barwą, światłem. Powietrze przytula się do ciebie, choćby był mróz, a ty masz w sobie tyle radości, że musisz ją rozdawać wokoło, bo się w tobie nie mieści Hoc fac - tak czyń. A tergo - od tyłu; z tyłu. I czarne włosy posiwieją. Safona |
|