[ dsivic @ 01.12.2017. 16:53 ] @
Pozdrav,

Radim na manjem CRM-u i u modulu zadataka korisnik otvara za datak, dodjeljuje ga sebi ili nekome drugom, pridruzuje dodatne korisnike kojih se zadatak tiče...

Tabele:

1. tasks (id,naziv,...)
2. users (id,ime,prezime)
3. tasks_users (task_id,user_id,color,order,seen)

Sada bi trebalo da svaki korisnik može za sebe lično podesiti boju, redoslijed... tu se nalazi i polje "seen"

query ide ovako
Code:

SELECT
    tasks.id,
    tasks.project_id,
    tasks.project_archived,
    tasks.parent_id,
    tasks.naziv,
    tasks.opis,
    tasks.datum,
    tasks.rok,
    tasks.company_id,
    tasks.costumer_id,
    tasks.old_cont_id,
    tasks.assigned_to_user_id,
    tasks.assigned_at,
    tasks.assigned_by_id,
    tasks.completed_at,
    tasks.completed_by_id,
    tasks.created,
    tasks.created_by_id,
    tasks.updated,
    tasks.updated_by_id,
    tasks.task_state_id,
    tasks.task_route_id,
    tasks.route_order,
    tasks.task_priority,
    tasks.is_private,
    tasks.radni_nalog_servisa_id,
    pacom.naziv AS company_naziv,
    pacom.phone AS company_phone,
    pacos.naziv AS costumer_naziv,
    pacos.mobile AS costumer_mobile,
    asto.username AS assigned_to_username,
    asto.first_name AS assigned_to_first_name,
    asto.last_name AS assigned_to_last_name,
    asby.username AS assigned_by_username,
    asby.first_name AS assigned_by_first_name,
    asby.last_name AS assigned_by_last_name,
    coby.username AS completed_by_username,
    coby.first_name AS completed_by_first_name,
    coby.last_name AS completed_by_last_name,
    crby.username AS created_by_username,
    crby.first_name AS created_by_first_name,
    crby.last_name AS created_by_last_name,
    upby.username AS updated_by_username,
    upby.first_name AS updated_by_first_name,
    upby.last_name AS updated_by_last_name,
    group_concat(
        tasks_users.user_id SEPARATOR ', '
    ) AS subscribed_users
FROM
    tasks
LEFT OUTER JOIN partners AS pacom ON pacom.id = tasks.company_id
LEFT OUTER JOIN partners AS pacos ON pacos.id = tasks.costumer_id
LEFT OUTER JOIN users AS asto ON asto.id = tasks.assigned_to_user_id
LEFT OUTER JOIN users AS asby ON asby.id = tasks.assigned_by_id
LEFT OUTER JOIN users AS coby ON coby.id = tasks.completed_by_id
LEFT OUTER JOIN users AS crby ON crby.id = tasks.created_by_id
LEFT OUTER JOIN users AS upby ON upby.id = tasks.updated_by_id
LEFT OUTER JOIN tasks_users ON tasks.id = tasks_users.task_id
WHERE
    tasks.project_id = 1
AND tasks.completed_by_id = 0
AND tasks.task_state_id = 10
AND (
    tasks.assigned_to_user_id = 9
    OR tasks.created_by_id = 9
    OR tasks.assigned_by_id = 9
    OR tasks_users.user_id = 9
)
GROUP BY
    tasks.id
ORDER BY
    tasks.`order` ASC /* OVDJE BI TREBAO DA IDE REDOSLIJED PO KORISNIČKOM SORTIRANJU tabel task_users */


Kako sam ja skonto, moram na svaku tabelu USERS dodati još jedan LEFT OUTER task_users ili da uradim subselect npr.

Code:

....
(SELECT color FROM task_users WHERE tasks_users.task_id = task.id and tasks_users.user_id = 9) as color,
(SELECT `order` FROM task_users WHERE tasks_users.task_id = task.id and tasks_users.user_id = 9) as `order`,
(SELECT seen FROM task_users WHERE tasks_users.task_id = task.id and tasks_users.user_id = 9) as seen
FROM
    tasks
....



Ili se sve ovo radi na drugi način?





[ djoka_l @ 01.12.2017. 18:46 ] @
Čim imaš problema sa upitom, siguran znak je da si omanuo sa dizajnom.
5 puta spajaš sa users tabelom, 2 puta sa partners.

Uz to, fiksirao si broj "uloga" usera na 5 i broj uloga partnera na 2.

Rešio bi gomilu problema da ta polja user_id izbaciš u neku tabelu, recimo, "involved", pa da tamo staviš role_id, user_id, task_id
[ dsivic @ 01.12.2017. 19:00 ] @
Dizajn je na mjestu, sve su to validna polja koja imaju odredenu ulogu,

da bi se izbjegao JOIN moglo bi se jedino u programskom code-u (PHP), baška uzeti lista usera pa ih kroz loop ubaciti u array zadataka...

imas li prijedlog za color, order, seen
[ bogdan.kecman @ 01.12.2017. 19:11 ] @
a sto bi "izbjegao JOIN" ? nije ti to mongo
[ dsivic @ 01.12.2017. 19:23 ] @
Nisam ni planirao, reko to bi mogla biti alternativa...al' odo od teme.

ajde Bogdane prijedlog za boja,order, seen :)
[ bogdan.kecman @ 01.12.2017. 19:41 ] @
necu se mesam, previse babica...
[ dsivic @ 01.12.2017. 20:36 ] @
ajde makar da ili ne za subselect
[ bogdan.kecman @ 01.12.2017. 20:57 ] @
ja se slazem sa kolegom, vezujes 4 tabele osam puta, ili 3 tabele 7 puta (cetvrta nije bitna) .. to je iz taka lose normalizovana baza... e sad, denormalizacija zarad nekih drugih benefita ima smisla ali ti si ovde denormalizovao i dobio probleme a ne benefite tako da.. vrati se ti na 3nf pa odatle resavaj problem ...

ako nece menjas model, onda nabudzi upit kako god da radi .. subselect je ok posebno sa 5.7 ili 8.0 mada ce jos po jedan join da bude verovatno brzi.. u svakom slucaju to jos dodatno obesmisljava taj db model... kontam da nemas problem da ti taj upit trci par desetina sekundi / minuta neces ga izvrsavati 10 puta na sat..
[ Predrag Supurovic @ 01.12.2017. 23:31 ] @
Šta je problem sa ovakvim JOIN-ovima i kako bi to drugačije rešili?
[ dsivic @ 02.12.2017. 00:01 ] @
ne mogu iz tabele tasks_users da dobijem polja color, order, seen jer se tu pojave i podaci od drugih korisnika pridruzenih zadatku...



[ Predrag Supurovic @ 02.12.2017. 09:01 ] @
Pitanje sam uputio ljudima koji kažu da baza nije dobro oragnizovana, bilo bi dobro da objasne kako bi trebalo to da se uradi.

Što se tvog pitanja tiče, gledajući tvoj kod, ne razumam čemu služi GROUP BY u upitu. Meni izgelda da ti pokušavaš da jednim upitom u jedan krusor izvučeš i podatke o tasku i podatke o userima koji su uključeni u taj task. Ja bih to uradio sa dva upita, jedan koji izvlači podatke o tasku a drugi koji lista povezane usere.

Što se tiče boje, pa da, ako hoćeš da za tasks.created_by_id izvuče i boju tog usera, onda moraš napraviti odgovarajući JOIN sa taks_users i tako za svako takvo polje.
[ dsivic @ 02.12.2017. 09:18 ] @
Group_by je zbog JOIN-a sa tasks_users, zbog cega se ponavljaju neki redovi.

I da, pokusavan to uraditi u jednom upitu.
[ Predrag Supurovic @ 02.12.2017. 09:19 ] @
Pa nemoj, listu subsrcibera izdvoj posebnim upitom.

[ dsivic @ 02.12.2017. 09:44 ] @
Ali onda moram imati loop i za svaki zadatak praviti upit...zar nije ovako optimalnije.
[ bogdan.kecman @ 02.12.2017. 11:42 ] @
@pedja, nezahvalno je redizajnirati bazu bez poznavanja problema, ja ne
mogu da nagadjam sta on sve hoce da resi i cemu sve sistem sluzi .. ali
mogu da kazem iz iskustva da kada radis 7 joina sa 3 tabele nekaj si
zas123al sa modelom.. ako je to jedino mesto gde ima takva kontrapcija i
poziva se jednom dnevno - koga briga, ako je nesto sto treba cesce onda
je problem ...

sa normalizovanom bazom ne bi bio mnogo "manji" upit, opet bi imao 8
joina samo bi bilo izmedju razlicitih (manjih) tabela i radio bi
znacajno brze a pametni sql serveri bi umeli i da optimizuju takav zahvat

sve to u slucaju da ovaj upit uopste treba tako (nisam uopste ulazio u
to sta hoce da izvede ovim upitom, iz iskustva takodje mogu da kazem da
u velikom % slucajeva kada neko radi self join 3 puta trebao je samo
drugaciji where za filter)
[ Predrag Supurovic @ 03.12.2017. 07:56 ] @
Mene je to interesovalo kao hipoteticki primer. Nema veze da li bi njemu to koristilo nego me zanima kako se može optimalnije uraditi ovako nešto.
[ dsivic @ 03.12.2017. 08:07 ] @
Ovaj upit je stalno u upotrebi. Kada korisnik otvori projekat, ovim upitom izlistam sve njegove zadatke, i za svaki zadatak korisnike koji su na neki nacin ukljuceni (napravio, dodijelio, dodijeljeno od,...osim korisnika iz tabele tasks_users - sa group concat uzmem sam njihove id brojeve).

Za sada nemam problema sa brzinom, baza je mala, u firmi imamo 10-tak zaposlenih.

Kada pogledam explain za query indexi su u upotrebi...

Do sada, color,order su bili vezani za zadatak i kada jedan korisnik napravi izmjenu, izmjene vaze i za ostale.

Pokusat cu sa subselectom...

U svakom slucaju hvala na pomoci.