infoarena

Comunitate - feedback, proiecte si distractie => Blog => Subiect creat de: Cosmin Negruseri din Mai 25, 2011, 03:13:09



Titlul: SQL query
Scris de: Cosmin Negruseri din Mai 25, 2011, 03:13:09
Comentarii la postul http://infoarena.ro/blog/sql-query


Titlul: Răspuns: SQL query
Scris de: Cosmin-Mihai Tutunaru din Mai 25, 2011, 09:22:54
Dacă nu se fac update-uri, cred că ar merge ceva de genul:
Pentru fiecare nod reţinem adâncimea faţă de rădăcină. Acum, un nod este părinte al unui nod dacă după ce urcăm nodul cu adâncimea mai mare până ajunge la aceeaşi adâncime cu nodul de adâncime mai mic şi dacă am ajuns în acelaşi nod (cu cel de sus). Petem face asta ţinând pentru fiecare nod al 2k - lea tată. Ar fi necesare cam log(adâncime_arbore) query-uri.
Sunt tare curios cum s-ar face altfel.


Titlul: Răspuns: SQL query
Scris de: Luci Filip din Mai 25, 2011, 10:12:23
Se poate stoca ierarhia folosind asa-zisul "nested model": fiecarui nod din structura ierarhica i se asociaza doua valori - stanga si dreapta. Numerotarea se face creascator, parcurgand arborele in preordine; la parcurgerea descendenta (dinspre parinte spre fii) se completeaza valoarea "stanga", iar la cea ascendenta (intoarcerea dinspre fii spre parinte) se compleateaza valoarea "dreapta". In acest mod fiecare valoare "stanga" are proprietatea ca se afla in intervalul definit de valorile "stanga" si "dreapta" ale oricaruia din parintii lui - cel direct sau cei indirecti. Folosind proprietatea asta se poate determina foarte usor daca un anumit nod din ierarhie este subordonat direct/indirect altui nod. Aproape la fel de usor se poate obtine o lista a tuturor nodurilor subordonate altui nod. Partea mai grea este sa adaugi noduri intr-o ierarhie... :)


Titlul: Răspuns: SQL query
Scris de: Mihai Calancea din Mai 25, 2011, 10:20:08
@stocarul
Daca nu sunt update-uri poti face o parcurgere df in care tii intr-un hash toate nodurile pe care le ai in stiva momentan si cand ajungi intr-un nod x rezolvi toate query-urile care il implica ca fiu  :) Dar banuiesc ca exista update-uri.

@luci
Dap, a ta e mai faina. Valoarea 'dreapta' a unui nod va fi cel mai mare numar asociat in subarborele sau?  :) La asta te refereai?


Titlul: Răspuns: SQL query
Scris de: Luci Filip din Mai 25, 2011, 10:50:44
@klamathix
Da, cel mai mare + 1, daca numerotam consecutiv.


Titlul: Răspuns: SQL query
Scris de: Pripoae Teodor Anton din Mai 25, 2011, 11:15:53
Facem pargurgerea euler a ierarhiei initiale, si introducem in baza de date pe rand in ordinea din parcurgerea euler. Vom tine id-ul minim si maxim al nodurilor din subarbore pt fiecare nod (sunt consecutive nodurile din subarbore). Pt un query se verifica daca t1[y] < t1[ x ] < t2[y].

Ce zice Cosmin Tutunaru e corect dar nu e practic. Nu prea e ok din punct de vedere SQL sa ti multe referinte catre acelasi tabel pe aceeasi obiect sql (linie din tabel). Cel putin asa stiu....


Titlul: Răspuns: SQL query
Scris de: Tirca Bogdan din Mai 27, 2011, 10:39:25
Cam aceeasi complexitate se obtine si cu LCA pentru constructie, apoi O(1) pe query. Verificam daca LCA dintre X si Y este nodul Y.
LE: Si cum zice cosmin se poate face LCA. Eu ma refeream la RMQ


Titlul: Răspuns: SQL query
Scris de: Pripoae Teodor Anton din Mai 27, 2011, 12:05:12
Este vorba de o baza de date, trebuie sa si mearga implementata. Intr-o baza de date nu poti tine un numar variabil de pointeri.


Titlul: Răspuns: SQL query
Scris de: Oltean Dorin din Iunie 21, 2011, 13:34:51
Nu stiu daca asta e solutia sau nu, dar mi se pare o idee destul de buna.
Este oarecum asemanatoare cu una din ideile prezentate anterior.

Fiecarei persoana din baza de date i se atribuie o valoare in plus care va ajuta la identificarea lantului ierarhic( not. lantIerarhicValue) .
Pe langa aceasta valoare, pentru a usura operatiunea de inserare este necesar sa retinem pentru fiecare Angajat cine este
 - superiorul
 - ultimul angajat dinaintea lui care se afla in aceeasi echipa cu el. (not. previousEmployee )
(ex. A este seful lui B, C si D - pentru C valoarea este B, pentru D valoarea este C)

lantIerarhicValue se determina asa.

Pentru radacina (let's call it CEO), avem o valoare destul de mare X
fiecare subordonat direct primeste o valoare mai mica decat X
ex. Daca CEO are subordonati pe A,B,C,D  acestora le dam valori
  • A.lantIerarhicValue= 1 * 1/maximumNumberOfDirectSubordinates * X;
  • B.lantIerarhicValue= 2 * 1/maximumNumberOfDirectSubordinates * X;
  • C.lantIerarhicValue= 3 * 1/maximumNumberOfDirectSubordinates * X;
  • D.lantIerarhicValue= 4 * 1/maximumNumberOfDirectSubordinates * x;

Acum pentru a raspunde la interogari de genul:
este A subordonat indirect al lui B putem verifica daca A.lantIerarhicValue  este intre B.lantIerarhicValue si .B.previousEmployee.lantIerarhicValue.

Una din problemele care ar putea sa para ar fi sa nu cunoasteam valoarea lui maximumNumberOfDirectSubordinates
Dar putem veni cu o solutie pentru aceasta problema:
Setam maximumNumberOfDirectSubordinates cu o valoare destul de mare. Daca la un anumit moment un sef are mai multi subordonati directi decat aceasta valoare(putem sa o dublam), crestem valoarea si actualizam intreg arborele.


Titlul: Răspuns: SQL query
Scris de: UPB-Oprea-Cosmin-Dumitru din Ianuarie 03, 2012, 18:25:43
Sunt de acord cu parcurgerea euler.E eficient si usor de implementat,excelent pentru concursuri.