Molim pomoć oko SQLa i malo grupiranja

Otkuda ti ovo B=C, pogledaj opet zadatak… (tipkam s mobitela)

B i C moraju biti one vrijednosti koje se nalaze uz A koji je prvi u grupi.

Da probam zdravo seljački. :slightly_smiling_face:
Imamo neku grupu, tipa: (2,4,6)… to su elementi iz polja A.

Želimo naći sve one retke gdje A tog retka pripada u tu grupu … a da dohvaćeni retci imaju one vrijednosti B i C kao što ih ima uz sebe vezane prvi A iz zadane grupe.

Mislim, mozemo jednostavnije i ovako reći:
A=2, groupA = (4,6)

Zadatak: Dohvati one retke koji imaju A da pripadaju u grupu @groupA, a da su tim retcima B i C polja ista kao što su B i C tamo gdje je A =2

Ok. Trebaš dva upita. Prvi hvata odgovarajuće vrijednosti b,c a sa drugim listaš sve redove sa tim vrijednostima?

Ps i ja sam na mobu pa teško odgovaram.

Sa dva upita je lako … htio bih jednim ako je moguće.

Izbjegavaću stručnu terminologiju kol’ko god mogu kako bi nam pronalazak rješenja bio što eventualniji.

Dobro će biti ako uspiješ i sa dva.
Ovo je iz početnog primjera

A, 	B, 	C
-----------
4 	27 	30
5 	20 	30
4	20	30
6	20	30

I sada mu proslijediš (4, 6), s kojom četvorkom bi trebalo da se uporedi šest?

1 Like

brzinski testirano i radi.

MSSQL

SELECT
a='2',
    b, 
    c, 
    COUNT(*) occurrences
FROM dbo.tablica
GROUP BY
    b, 
    c
HAVING 
    COUNT(*) >1;

Abort, abort… ne radi dobro… :smiley:

Možeš joinati tablicu samu sa sobom.

SELECT tableA.*
FROM group_table tableA
    JOIN group_table tableB
    ON tableA.b = tableB.b
    AND tableA.c = tableB.c
WHERE tableA.a IN ( 4, 6 )
    GROUP BY tableA.a;
1 Like

Potom te sačeka ovo.

:man_facepalming:

A se ponavlja.

U biti, mislim da može još jednostavnije:

EDIT: mislio sam da imam SQL u glavi, ali ne mogu bez tablice. Kasno je jbg.

@nosiocgrupe je varijabla za polje A. U primjeru je to 2,3,4,5 ili 6

SELECT *
FROM tablica
WHERE CAST(B AS VARCHAR(10)) + ‘#’ + CAST(C AS VARCHAR(10)) IN (SELECT DISTINCT CAST(B AS VARCHAR(10)) + ‘#’ + CAST(C AS VARCHAR(10)) FROM tablica WHERE A = @nosiocgrupe)
OR CAST(C AS VARCHAR(10)) + ‘#’ + CAST(B AS VARCHAR(10)) IN (SELECT DISTINCT CAST(B AS VARCHAR(10)) + ‘#’ + CAST(C AS VARCHAR(10)) FROM tablica WHERE A = @nosiocgrupe)

Nije mi baš jasno tvoje rješenje…ali si mi dao odličnu ideju. Trebam dodati novo polje u tablicu: “BC” koje će biti u startu mergano B i C (kao što ti castaš i zbrajaš) …i onda bi ovo trebalo raditi:

SELECT * FROM table WHERE A in @groupA and BC IN (SELECT BC from table WHERE A=@A)

:slight_smile:

Inače mi se ne sviđa to castanje…jer mi se čini da tu indexi onda ne djeluju… pošto database engine mora prvo sva polja castati i zbrojiti da bi znao sa čime ima posla. Ovako ako se od starta vodi “BC” polje …ono je svojevrstan index.

Inače moram priznati da nisam skužio tvoj OR dio u queryu… zašto si zarotirao B i C …i čemu taj dio uopće.
Osim toga, imaš varijablu @nosiocgrupe, ali nigdje i varijablu @grupaA unutar koje se traži. No to bi valjda bilo trivijalno dodati na tvoj upit …samo velim, nije mi jasan čemu OR dio.

Probat ću. :slight_smile:

U pravu si, krivo sam se izrazio. Tim pristupom su dva upita minimalna…tj. tim pristupom treba ​onoliko upita koliko se puta pojavljuje u tablici redak sa nosiocom grupe + 1 extra upit.

To i jeste razlog zašto tražim riješenje koje riješava sve jednim upitom…da su uvijek dva upita, nebi me to niti žuljalo, ali upravo zato što broj upita raste ovisno o slučaju, takvo riješenje nije nikako skalabilno. Jer može doći situacija da ima onda i preko 1000 upita… što nije zdravo…

Ne radi… al sviđa mi se ovo joinanje tablice same sa sobom. :wink:

I ovo radi:
SELECT * FROM table WHERE A in @groupA and BC IN (SELECT BC from table WHERE A=@A)

tako da je case solved. :slight_smile:



Nego, još jedno pitanje vezano uz SQL temu…

Jel moguće napraviti na razini SQL-a rekurzivni upit?

Recimo da imamo tablicu:

		A | B
		------
		1	4
		4	8
		8	6

Gdje je to nekav odnos parent-child. Znači A je parent od B.
I sada želimo naći sve roditlje od B=6 uz stablo skroz do vrha.

Znači prvi roditelj od 6 je 8.
Pa roditelj od 8 je 4
Pa roditelje od 4 je 1
1 više nema roditelja i tu smo znači stigli do vrha stabla od child=6 do njegovog izvornog roditelja=1.

Jel ikako moguće dohvatiti tako rekurzivno sve roditelje uz stablo, bez da se iterira sa više querya?

Hvala.

Pojašnjenje…
Select je za obje kombinacije BC i CB zato je upit s OR.

Podselect
SELECT DISTINCT CAST(B AS VARCHAR(10)) + ‘#’ + CAST(C AS VARCHAR(10)) FROM tablica WHERE A = @nosiocgrupe

za @nosiocgrupe = 4 vraća rezultat
27#30
20#30

Dalje se provjerava svaki slog da li zadovoljava kriterij da se nalazi u podselectu.

Da, ovo ne može koristiti indexe jer dizajn tablice nije dobar.

Zaista ne znam da li se može, ja znam da ne znam.
Nego pitanje, zašto forsiraš na rješavanju ovakvih upita kroz jedan select?
Puno elegantnije se mogu riješiti kroz procedure. Također treba razmisliti o redizajnu bazu kada se ukaže potreba.

Ma bitno mi je da je jedna (remote) konekcija na bazu … kod ovakvih upita koji ovisno o situaciji bi mogli završiti i na xx konekcija.

… a sada, ako procedure to omogućavaju, to će biti isto super rješenje.
Vidiš, nisam radio sa procedurama…trebalo bi. :slight_smile:
Nisam niti znao da mySQL to podržava …a koliko vidim po Googleu, čini se da podržava.

I dalje mi nije jasno čemu obje kombinacije… hmm.

Podržava. Isprobano, radi

Koliko si toga napisao učinilo mi se da treba. Ako ne treba, makne se od OR…

Generalniji naslov ti je “Managing hierarchical data in MySQL”.

To što si opis’o se zove “Adjacency list model”.

Ali prije nego se zaputiš tamo, pročitaj o još jednom načinu a to je “The nested set model” koji bi bilo bolje da upotrijebiš.

Nema na čemu.

1 Like