ugrás a tartalomhoz

MySQL - SELECT több táblából, átlaggal

peachman · 2013. Már. 19. (K), 16.57
táblák (nem az összes mezővel, csak ami hirtelen kell)
borok (id, nev, pinceszet_id)
pinceszetek (id, nev, borvidek_id, telepules_id)
borvidekek (id, nev)
telepulesek (id, telepules)
ertekelt_borok (id, bor_id, ertek_szam)
ertekelt_pinceszetek (id, pinceszet_id, user_id, ertek_szam)

amiket vissza kellene kapnom:
- pinceszet id
- pinceszet nev
- borvidék név
- település név
- pincészet értékelések száma

és a komplikáció:
a pincészetek önálló értékelése mellett (ertekelt_pinceszetek) működik egy automatikus értékelés is.

ez azon alapul, hogy:
minden bort értékelhetnek (1-5-ig) a felhasználók (ertekelt_borok). így kialakul a borok átlagos értéke. ezeket kellene egy adott pincészet boraira megcsinálnom úgy, hogy a pincészet borainak egyenkénti átlaga alapján visszakapjak egy 1-5-ig terjedő pincészetre vonatkoztatott átlagot. tehát a pincészet megitélését a borainak a megitélése alapján.

Erre próbálok valami egymésba ágyazott SELECT-et csinálni, de egyelőre nem sikerül.
 
1

Ha nem tervezed kifejteni a

hunkris · 2013. Már. 19. (K), 18.09
Ha nem tervezed kifejteni a problémát, vagy nem adsz mellé kódot, nem fogunk tudni segíteni.
2

Nem kell egymásba ágyazott SELECT

zforgo · 2013. Már. 19. (K), 18.43
Szerintem több join elég.

select p.*, avg(eb.ertek), avg(ep.ertek) from pinceszetek p 
	left join borok b on p.id = b.pinceszet_id 
	left join ertekelt_borok eb on eb.bor_id = b.id
	left join ertekelt_pinceszetek ep on ep.pince_id = p.id 
group by p.id;
Így megkapod a pincészetre és borokra vonatkozó átlagokat külön. Ezt a két értéket utána ugyanúgy átlagolhatod.

Nem lesz gyors. Nem tudsz súlyozni és valószínű nem érkezik annyi értékelés, mint amennyiszer meg kell ezt jeleníteni. Ezért én gondolkoznék egyéb más technológiák behozatalával ha ismernénk a feladat ezen részét.
4

Hajjaj

Pepita · 2013. Már. 19. (K), 18.58
Nem lesz gyors
Hát, ha csak magyar pincészetekben és borokban gondolkodsz, akkor is erős vas kell ehhez, ha mondjuk minden borra van átlag 20 értékelés... Ha 1000 pince, mindegyiknek 5 bora, akkor 1000 x 5000 x 100000 = 5 x 10^11 db rekordot állítottál most elő, arra megy a groupby. (Ha jól saccoltam.)
5

Hogy jött ki ez az érték?

zforgo · 2013. Már. 19. (K), 19.15
Nem kötekedni akarok, de akárhogy gondolkodom nem látom, hogyan jött ki nálad ez a rekordszám.
8

Kis túlzással :)

Pepita · 2013. Már. 19. (K), 19.35
1000 : pince;
5000 : pincénként 5 bor;
100000 : 5000 borra egyenként 20 értékelés.

Szerk.: a szorzás fejben történt, nem tudom, hogy jó-e :)

Nyilván te nem SELECT-eket ágyaztál egymásba, de a JOIN sem sokkal jobb (MySql-ben), ha jól tudom. És a GROUP BY az így létrejövő rekordhalmazon lesz, tehát előbb "legyártódik" a sok rekord. Pont erre céloztam, hogy az adatbázisszerkezet nem az igazi.
12

Ugye azt te sem gondolod,

Joó Ádám · 2013. Már. 19. (K), 23.08
Ugye azt te sem gondolod, hogy egy join eredménye valóban egy Descartes-szorzat lesz? :) Az adatbáziskezelők egyik feladata a lekérdezések optimalizálása.
14

Nemis

Pepita · 2013. Már. 20. (Sze), 18.45
Ajánlanám figyelmedebe 8-as kommentemet is:
Kis túlzással
Nyilván te nem SELECT-eket ágyaztál egymásba
Ezzel együtt legtöbbször célravezetőbb megoldás + 1-2 mező a táblákban, mint a JOIN JOIN JOIN .... Motortól függ, mennyire jól optimalizálja, ill. az esetleges külső kulcsoktól, stb.
3

Egy lekérdezésben?

Pepita · 2013. Már. 19. (K), 18.51
Amikor pontoznak egy bort, akkor a vele azonos pinceszet_id-s borok pontjait (AVG) lekéred egy SELECT-el, utána megy az UPDATE az ertekelt_pinceszetek-re.

Itt a táblastruktúra az, ami nem az igazi, de mivel ez csak az, "ami hirtelen kell", nemigazán tudok konkrétumot mondani. Nem derül ki a táblákból, hogy hol van egy bornak az átlagpontszáma. Sehol? Mert az jó lenne. (Az esetek többségében "olcsóbb" táblánként 1-2 plusz (szám) mező, mint jobbra-balra sok JOIN-t használni.)
6

Az a helyzet ezzel, hogy a

peachman · 2013. Már. 19. (K), 19.20
Az a helyzet ezzel, hogy a borok értékelésénél tárolnom kell, hogy melyik user értékelte már, hogy újabb értékelése a meglévőt módosítsa. Illetve írhat hozzá szöveges értékelést is.
Aztán lehet a pincészetet is értékelni számokkal szöveges módon is.

Jelenleg:
ertekelt_borok (id, bor_id, user_id, ertek_szam, ertek_txt)
ertekelt_pinceszetek (id, pinceszet_id, user_id, ertek_szam, ertek_txt)

A lényeg, hogy ebben a listában úgy kell a pincészetnek értéket kijeleznem, hogy az ertekelt_borok táblából veszem az ő boraihoz tartozó egyéni értékeléseket és abból csinálok átlagot. Tehát gyakorlatilag a borai alapján ítélem meg.

Belegondolva lehet, hogy jobban járnék a pincészethez egy plusz mezővel, amit egy borához érkezett új értékelés esetén pontosítok. Ekkor ezt az átlagolást csak akkor kellene megcsinálnom és listázáskor csak lekérnem.
Gondolom ugyanez jó lenne a pincészet saját értékelésénél is.

Az mennyire volna jó megoldás, ha:

borok (id, nev, pinceszet_id, ertekeles)
pinceszetek (id, nev, ertekeles)
ertekelt_borok (id, user_id, bor_id)
ertekelt_borok_txt (id, bor_ertekeles_id, txt)
ertekelt_pinceszetek (id, user_id, pinceszet_id)
ertekelt_pinceszetek_txt (id, pince_ertekeles_id, txt)

Tehát a szöveges értékeléseket is külön táblába tenném, illetve a borok és pincék táblában tárolnám az átlagot.
7

Jobbnak néz ki

Pepita · 2013. Már. 19. (K), 19.33
Bár az is jó lenne, ha beszédesebben neveznéd el az oszlopokat, pl. ott, ahol átlagérték van. A szöveges értékelést nem feltétlen kell külön venni, főleg ha egy Júzer abból is csak egyet követhet el.

Az ertekelt_borok-nál és ertekelt_pinceszetek-nél most nincs pontszám (és máshol sem látom). És hiányoznak a korábbi cím, borvidék cuccok is.
Szerintem ülj le egy üres papírral és ceruzával a kezedben, nyugodtan gondold végig és rajzold (írd) le az összes táblát és relációt. (Én is így szoktam :))
Ha jól végiggondolod, most már menni fog.
9

Persze. Csak gyorsan

peachman · 2013. Már. 19. (K), 19.42
Persze. Csak gyorsan próbáltam a gondolatmenetet felvázolni. Köszönöm az infót.
10

Szívesen

Pepita · 2013. Már. 19. (K), 20.25
Majd tedd ki a táblákat, ha gondolod, más is tanulhasson belőle (kódszínező!).
11

A lekérdezésre gondolsz? A

peachman · 2013. Már. 19. (K), 22.06
A lekérdezésre gondolsz?

A szöveges értékelést azért akarom külön táblába tenni, mivel a számokkal történő értékelés mellé nem kötelező szövegeset is írni. Csak egy opció. Ha egy táblában lesz mindkettő, akkor a legtöbb helyen üresen fog állni csak.
15

És a táblákra

Pepita · 2013. Már. 20. (Sze), 18.52
De mindegy, nekem nem fontos.

Attól még teheted egybe, ha mondjuk elfér (VAR)CHAR mezőben is, és nem kell indexelni, stb., így nem lesz lényegesen "nagyobb" az egy táblád, tehát lassabb sem. Viszont könnyebben kezelheted az egy Júzer - egy vélemény dolgot.
13

szerintem

szabo.b.gabor · 2013. Már. 20. (Sze), 11.46
SELECT pinceszet_id,AVG(ertek_szam)
FROM borok b INNER JOIN ertekelt_borok eb ON b.id=eb.bor_id
GROUP BY pinceszet_id
szerintem ennyi..