Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.

Pomoć za početnika - sve kombinacije

[es] :: MySQL :: Pomoć za početnika - sve kombinacije

[ Pregleda: 3485 | Odgovora: 14 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

__Mrgud__

Član broj: 100453
Poruke: 36
5.134.107.*



+5 Profil

icon Pomoć za početnika - sve kombinacije30.09.2015. u 23:34 - pre 103 meseci
Pozdrav svima!

O SQLu znam malo do nimalo, ali pokušavam ponešto da odradim i da naučim. Imam sledeće problemče. U tabeli za primer:

Code:

CREATE TABLE `lokacije` (
  `lokacija` varchar(10)  NOT NULL DEFAULT 'lokacijaX',
  `kutija` varchar(10)  NOT NULL DEFAULT 'kutijaX'
);

INSERT INTO `lokacije` 
    (`lokacija`,`kutija`) 
VALUES
    ('lokacija1','kutija11'),
    ('lokacija1','kutija12'),
    ('lokacija1','kutija13'),
    ('lokacija2','kutija21'),
    ('lokacija2','kutija22'),
    ('lokacija2','kutija23'),
    ('lokacija3','kutija31'),
    ('lokacija3','kutija32'),
    ('lokacija3','kutija33');


Pokušavam jednim SELECT upitom da dobijem nešto ovakvo:

Code:

lokacija      |    spisak
---------------------------------------------
lokacija1     |    kutija11,kutija12,kutija13
lokacija2     |    kutija21,kutija22,kutija23
lokacija3     |    kutija31,kutija32,kutija33


Dakle, potreban mi je za svaku pojedinačnu lokaciju - jedan string koji će sadržati sve kutije koje su na njoj trenutno smeštene. Pokušao sam sa višestrukim JOIN-om, sa i bez ON, ali uglavnom dobijam zlo od upita koji traje ohoho i ne daje šta treba. GROUP BY takođe ne pomaže ili ga ne koristim kako valja. Problem je što za svaku lokaciju broj kutija varira i može ih biti do 15, a nekako intuitivno osećam da petnaestostruki JOIN tabele sa samom sobom verovatno nije baš pravi put do rešenja :) Sve u svemu, malo sam se pogubio u upitima koje sam probao, što samostalno što skrpljenih sa stackoverflow, pa bi mi značila pomoć.

Inače, prava tabela sa kojom radim je relativno mala, ~15k redova, pritom je ćopava i bez indeksa, ali ne tražim trenutno neko megaoptimalno rešenje, ovo će se izvršiti jednom i više nikada, tako da što se mene tiče upit može da trči i pola sata samo ako dobijem na kraju šta mi treba.

Hvala svima unapred, svaka pomoć je dobrodošla.
 
Odgovor na temu

bogdan.kecman
Bogdan Kecman
"specialist"
Oracle
srbistan

Član broj: 201406
Poruke: 15887
*.com
Via: [es] mailing liste

Sajt: mysql.rs


+2377 Profil

icon Re: Pomoć za početnika - sve kombinacije01.10.2015. u 00:27 - pre 103 meseci
treba ti group_concat:
https://dev.mysql.com/doc/refm...ons.html#function_group-concat

select lokacija, group_concat(kutija SEPARATOR /||/',') as spisak from
lokacije group by lokacija;
 
Odgovor na temu

__Mrgud__

Član broj: 100453
Poruke: 36
..7.in-addr.arpa.vipmobile.rs.



+5 Profil

icon Re: Pomoć za početnika - sve kombinacije01.10.2015. u 07:58 - pre 103 meseci
Code:

4470 row(s) returned
0.110 sec/0.015 sec


Ruke ti se pozlatile, Bogdane! Hvala! :)

A kad smo već tu, edukacije radi - da li postoji neki "pešački" način da se do ovoga stigne? Pritom, pretpostavljam da group_concat() isto radi nešto pešački u pozadini?

Moja ideja je bila da (nekom magijom) stignem do tabele sa L redova (broj lokacija) koja će imati K kolona (maksimalan broj kutija na lokaciji), pa onda concat_ws() za sve kutije. Ali mi je problem što je broj kutija promenljiv po lokacijama, pa bih negde imao stringove tipa "kutijaxy,,,,", a negde "kutijaab,kutijabc,,". A ovaj group_concat radi baš ono što treba...
 
Odgovor na temu

bogdan.kecman
Bogdan Kecman
"specialist"
Oracle
srbistan

Član broj: 201406
Poruke: 15887
*.com
Via: [es] mailing liste

Sajt: mysql.rs


+2377 Profil

icon Re: Pomoć za početnika - sve kombinacije01.10.2015. u 10:00 - pre 103 meseci
izvini ali nemam pojma sta sad pitas :D
 
Odgovor na temu

dusans
Stojanov Dušan
Pančevo

Član broj: 9551
Poruke: 1343
*.dynamic.sbb.rs.



+311 Profil

icon Re: Pomoć za početnika - sve kombinacije01.10.2015. u 10:15 - pre 103 meseci
Ja sam ga razumeo, pita da li postoji alternativni način da dobije to isto a koji bi radio ovako:

1. Select u "pivot" tabelu gde su za neku grupu njene kutije raspoređene po pivot kolonama.
2. Select sa concat_ws() iz "pivot" kolona da bi dobio npr. "kutijaab,kutijabc,,,"
 
Odgovor na temu

__Mrgud__

Član broj: 100453
Poruke: 36
..7.in-addr.arpa.vipmobile.rs.



+5 Profil

icon Re: Pomoć za početnika - sve kombinacije01.10.2015. u 11:17 - pre 103 meseci
Dušan je na pravom putu - ovo što je objasnio je bila moja zamisao kako da rešim ovo. :)

A pitanje sam smuljao, zapravo su dva pitanja:

- Da li je moguće dobiti identičan rezultat bez korišćenja group_concat() već samo koristeći "obične" SELECT, JOIN, GROUP BY, itd?
- Šta tačno group_concat radi kada se pozove?
 
Odgovor na temu

jablan

Član broj: 8286
Poruke: 4541



+710 Profil

icon Re: Pomoć za početnika - sve kombinacije01.10.2015. u 11:25 - pre 103 meseci
Citat:
__Mrgud__: - Šta tačno group_concat radi kada se pozove?

Isto što i SUM(), samo za stringove. :)
 
Odgovor na temu

djoka_l
Beograd

Član broj: 56075
Poruke: 3445

Jabber: djoka_l


+1462 Profil

icon Re: Pomoć za početnika - sve kombinacije01.10.2015. u 11:37 - pre 103 meseci
Proguglaj pivot queries. MS SQL, Oracle imaju pivot. MySql ima group_concat. Nije isto, ali radi sličan posao.
 
Odgovor na temu

bogdan.kecman
Bogdan Kecman
"specialist"
Oracle
srbistan

Član broj: 201406
Poruke: 15887
*.com
Via: [es] mailing liste

Sajt: mysql.rs


+2377 Profil

icon Re: Pomoć za početnika - sve kombinacije01.10.2015. u 22:04 - pre 103 meseci
da li je moguce - jeste moguce je, mozes delom da pises kod na klijentu,
mozes stored procedure, mozes iz vise upita.... sve u svemu moze, ali za
mysql ovo je pravilan nacin

sta radi group_concat, dadoh ti link na dokumentaciju, ako ti nije jasno
nesto iz dokumentacije reci sta ti tacno nije jasno ali nemoj da pitas
"sta radi" pre nego procitas dokumentaciju
 
Odgovor na temu

agvozden
Aleksandar Gvozden
founder
Info-G
Beograd

Član broj: 37813
Poruke: 1122
*.dynamic.sbb.rs.

Sajt: www.gvozden.info


+68 Profil

icon Re: Pomoć za početnika - sve kombinacije01.10.2015. u 22:04 - pre 103 meseci
A da pročitaš nešto o relacionim bazama podataka na primer?

Ne razumem ove što rešavaju konkretne probleme, a nemaju nikakvu osnovu. Ne moraš fakultetski, ali barem osnove...
 
Odgovor na temu

__Mrgud__

Član broj: 100453
Poruke: 36
5.134.107.*



+5 Profil

icon Re: Pomoć za početnika - sve kombinacije02.10.2015. u 12:05 - pre 103 meseci
Citat:
bogdan.kecman:
da li je moguce - jeste moguce je, mozes delom da pises kod na klijentu,
mozes stored procedure, mozes iz vise upita.... sve u svemu moze, ali za
mysql ovo je pravilan nacin


OK, fair enough :) Pošto učim, pitanje je bilo više za slučaj - šta ako sutra sednem pred PGSQL gde nemam na raspolaganju group_concat? Naravno, 99% ću imati neku ekvivalentnu agregatnu funkciju, ali me je interesovao "SQL način rešavanja", iako se slažem da je to više pitanje za "Baze podataka" nego za MySQL forum.

Citat:
bogdan.kecman:
sta radi group_concat, dadoh ti link na dokumentaciju, ako ti nije jasno
nesto iz dokumentacije reci sta ti tacno nije jasno ali nemoj da pitas
"sta radi" pre nego procitas dokumentaciju


Izvinjavam se, nisam se dobro izrazio: jesam pročitao dokumentaciju i vrlo je jasno ŠTA funkcija radi, u smislu efekta koji se dobija - concatenate svih non-NULL vrednosti iz grupe definisane sa GROUP BY. Ali time se vraćamo na suštinski problem koji nisam umeo da rešim - KAKO group_concat() dobija sve non-NULL vrednosti iz grupe? To je ono na šta sam mislio u drugom postu rečenicom "Pritom, pretpostavljam da group_concat() isto radi nešto pešački u pozadini?". A funkcija u pozadini radi:
- uzme sve non-NULL vrednosti iz grupe -> ono što nisam umeo da uradim
- uradi concatenate_ws() nad tim vrednostima -> ono što jesam umeo da uradim

Citat:
jablan:
Isto što i SUM(), samo za stringove. :)

Ovo je zapravo super odgovor :) Da sam na ovaj način razmišljao, mogao sam da izguglam rešenje...

 
Odgovor na temu

bogdan.kecman
Bogdan Kecman
"specialist"
Oracle
srbistan

Član broj: 201406
Poruke: 15887
*.com
Via: [es] mailing liste

Sajt: mysql.rs


+2377 Profil

icon Re: Pomoć za početnika - sve kombinacije02.10.2015. u 14:38 - pre 103 meseci
pa radi kao i svaka druga agregatna funkcija :D
agregatna funkcija dobija sve vrednosti za neku grupu i onda radi
"stagod" sa njima, vadi averaga, sabira ih, spaja ih ... stagod

pogledaj: https://dev.mysql.com/doc/refman/5.5/en/create-function-udf.html

Citat:

An |AGGREGATE| function works exactly like a native MySQL aggregate
(summary) function such as |SUM| or |COUNT()|
.
For |AGGREGATE| to work, your |mysql.func| table must contain a |type|
column


dalje:
http://www.codeproject.com/Art...3/MySQL-User-Defined-Functions
Citat:


Now some words to aggregate functions. When your UDF is an aggregate
function you have to add some more functions and some functions are used
in a different way. The calling sequence is:

1. Call |MyTest_init |to allocate memory (just like a normal UDF)
2. MySQL sorts the table according to the GROUP BY statement
3. Call |MyTest_clear |for the first row in each group
4. Call |MyTest_add |for each row that belongs to the same group
5. Call |MyTest |to get the result when the group changes or the last
row has been processed
6. Repeat 3 to 5 until all rows have been processed
7. Call |MyTest_deinit |to free any used memory

Now let's look at the new functions needed for the aggregate function.
In this example we'll simply add up all the values. (like the native
|SUM |function)
Code:


void MyTest_clear(UDF_INIT *initid, char *is_null, char *error)
{
        /*The clear function resets the sum to 0 for each new group Of course
you have to allocate a longlong variable in the init function and assign
it to the pointer as seen above */
        *((longlong*)initid->ptr) = 0;
}

void MyTest_add(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error)
{
        //For each row the current value is added to the sum         *((longlong*)initid->ptr) = *((longlong*)initid->ptr) + 
                                    *((longlong*)args->args[0]);
}

longlong MyTest(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error)
{
        //And in the end the sum is returned         return *((longlong*)initid->ptr);
}



...
 
Odgovor na temu

bogdan.kecman
Bogdan Kecman
"specialist"
Oracle
srbistan

Član broj: 201406
Poruke: 15887
*.dynamic.sbb.rs.

Sajt: mysql.rs


+2377 Profil

icon Re: Pomoć za početnika - sve kombinacije02.10.2015. u 14:51 - pre 103 meseci
Citat:
__Mrgud__:
ali me je interesovao "SQL način rešavanja"


pa "sql nacin" resavanja tvog problema je sa agregatnom funkcijom, ako hoces da dobijes to sto si trazio ... mada to sto si trazio nije klasican "sql nacin" .. klasican sql nacin bi bio sa temp tabelama oko kojih se vrtis (pivot) ili ako rdbms ima podrsku za moderne sql extenzije sa window sql funkcijama :
npr: http://www.postgresql.org/docs...nt/static/tutorial-window.html

 
Odgovor na temu

__Mrgud__

Član broj: 100453
Poruke: 36
..7.in-addr.arpa.vipmobile.rs.



+5 Profil

icon Re: Pomoć za početnika - sve kombinacije02.10.2015. u 20:16 - pre 103 meseci
Super, eto materijala za čitanje! Hvala za info, Bogdane, i izvini za cimanje! :)
 
Odgovor na temu

bogdan.kecman
Bogdan Kecman
"specialist"
Oracle
srbistan

Član broj: 201406
Poruke: 15887
*.com
Via: [es] mailing liste

Sajt: mysql.rs


+2377 Profil

icon Re: Pomoć za početnika - sve kombinacije02.10.2015. u 20:23 - pre 103 meseci
nema cimanja, samo ti citaj i pitaj sta nije jasno .. MySQL ne podrzava
ove moderne SQL:2008 i SQL:2011 stvari, nema windowed funkcije etc etc
... to ako zelis postgresql ti je najbolje resenje on je sto se tih
stvari tice kompletniji i od nekih bubreg skupih rdbms-a
 
Odgovor na temu

[es] :: MySQL :: Pomoć za početnika - sve kombinacije

[ Pregleda: 3485 | Odgovora: 14 ] > FB > Twit

Postavi temu Odgovori

Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.