SQL Query ,JOIN & MAX
Ik zit al een dag met een hele irritante query , het zou ideaal zijn als deze goed zou werken.
Ten eerste De tabellen.
Tabel : tvseeker > Deze tabel slaat tv series gegevens op
Tabel : tv_infoseeker -> Deze tabel slaat info over de serie op mits deze aanwezig is.
TABEL TVSEEKER :
id int(255)
n Naam
epi Episode (int)
season Season (int)
a Unix time
f Formaat > 1=xvid ,2=dvdrip,3=HD,4=DVD
cat Categorie -> 1= eerste keer gepost 2=repost
TABEL tv_infoseeker
Tekst
genres
IMages
Ok mijn probleem :
Er komen elk uur tig nieuwe serie releases in de tabel.
Voorbeeld :
Heroes seizoen 3 episode 4 , HD , 3 uur geleden
Maar kan ook deze zijn
Heroes seizoen 3 episode 1,XVID, 1 uur geleden.
Ik wil op een pagina het volgende :
Een lijst met :
- Unieke serie namen ( group by N).
- Alleen het nieuwe seizoen en de laatste(hoogste) episode.
- Gesorteed op laatst toegevoegd.
Ik heb een querie die werkt d.m.v. subqueries , maar die is veeels te sloom. ( 3,8 sec).
rel=tvseeker
info=tvseeker_info
SELECT rel.n , rel.a , rel.season , rel.f ,rel.epi ,info.n, info.genres , info.tekst,info.image
//
FROM tvseeker as rel, tvseeker_info as info
WHERE rel.n=info.n
AND rel.a=(SELECT max(a) FROM tvseeker WHERE n=rel.n )
AND rel.season=(SELECT max(season) FROM tvseeker WHERE n=rel.n )
AND b.epi=(SELECT max(epi) FROM tvseeker WHERE n=rel.n AND season=rel.season )
AND b.cat='1' AND (b.f='1' OR b.f='3')
GROUP BY rel.n ORDER BY rel.a DESC
//
Ik ben begonnen met deze querie (0,3030 sec), die ieder geval het nieuwste seizoen bevat ,maar dus ook episodes selecteert die niet het nieuwst zijn.
SELECT rel.n, rel.a, rel.season, rel.f, rel.v, rel.epi, info.genres, info.tekst, info.image
FROM tvseeker rel INNER JOIN (
SELECT rel_extra.n, max( rel_extra.a ) AS a, MAX( rel_extra.season ) AS season, info_extra.genres, info_extra.tekst, info_extra.image
FROM tvseeker AS rel_extra
INNER JOIN (
SELECT genres, n, tekst, image
FROM tvseeker_info)
AS info_extra ON rel_extra.n = info_extra.n
GROUP BY info_extra.n
)
AS info ON rel.n = info.n AND rel.a = info.a
AND rel.season =info.season
AND (rel.f = '1' OR rel.f = '3')
GROUP BY rel.n
ORDER BY rel.a DESC
Weet iemand hoe ik met de laatste querie toch - alleen- de laatste episode kan krijgen?
Good luck ;)
deze tutorial over het juiste gebruik van GROUP BY.
Verder heb ik ook mijn twijfels bij je datamodel, zoals het er nu naar uit ziet klopt dat ook niet. Wat voor gegevens sla je in de tabel info_seeker op? En hoe koppel je die gegevens aan de series in tv_seeker? Wellicht dat het handig is om ook deze tutorial over normaliseren eens te lezen.
Allereerst zijn de queries die je nu gebruikt ongeldig, je gebruikt de GROUP BY clausule namelijk op een verkeerde manier! Zie ook Verder heb ik ook mijn twijfels bij je datamodel, zoals het er nu naar uit ziet klopt dat ook niet. Wat voor gegevens sla je in de tabel info_seeker op? En hoe koppel je die gegevens aan de series in tv_seeker? Wellicht dat het handig is om ook deze tutorial over normaliseren eens te lezen.
Hoe zou je dan unieke series krijgen? distinct is hier niet geschikt voor.
en omdat ik de functie MAX gebruik moet ik wel een GROUP BY clausule gebruiken.
in de tabel info_seeker staan : ,tekst,plaatje etc staat over series gelinkt door de naam.
Zou jij dan een oplossing weten deze querie te verbeteren?
Maar om eens te beginnen met je datamodel. Tabellen koppelen mbv een varchar is over het algemeen niet erg efficient. Gebruik hier liever altijd een id voor! Verder doet een kolomnaam als 'genres' mij vermoeden dat je in 1 veld meerdere genres opslaat, dat is niet correct (zie tut over normaliseren). Zoals ik het nu zie, kan de meest informatie uit je info tabel, gewoon in de tabel met series opgenomen worden (elke serie heeft immers maar 1 stuk informatie en extra tekst). Voor de genres en formaten zul je dan wel een aparte tabel moeten gebruiken en eventueel voor de afbeeldingen ook, mocht je meerdere afbeeldingen per serie kunnen hebben. Als je dit alles samenvoegt en de normalisatie regels hanteert, zou je ongeveer op het volgende uitkomen:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
series
-------
id INT (PK)
name VARCHAR
season INT
episode INT
release DATE
format_id INT (FK: formats.id)
image VARCHAR
info TEXT
genres
--------
id INT (PK)
genre VARCHAR
serie_genre
--------------
id_serie INT (PK, FK: series.id)
id_genre INT (PK, FK: genres.id)
formats
---------
id INT (PK)
format VARCHAR
-------
id INT (PK)
name VARCHAR
season INT
episode INT
release DATE
format_id INT (FK: formats.id)
image VARCHAR
info TEXT
genres
--------
id INT (PK)
genre VARCHAR
serie_genre
--------------
id_serie INT (PK, FK: series.id)
id_genre INT (PK, FK: genres.id)
formats
---------
id INT (PK)
format VARCHAR
Je zou zelfs nog verder kunnen normaliseren door de seasons en episodes ook uit elkaar te trekken en daar dus aparte tabellen voor te gebruiken. Op die manier beschouw je een nieuwe episode niet als aparte serie maar als onderdeel van een bepaalde serie.
Wat betreft je queries, hetgeen je wilt bereiken doe je niet met MAX. Dit kan je veel eenvoudiger doen door te sorteren op bijvoorbeeld season en episode en daarbij de juiste richting (DESC) op te geven...
Maar goed, ik zou eerst nog eens goed naar je datamodel kijken. Want afhankelijk daarvan komen je queries er ook anders uit te zien.
Normaliseren moet ik idd doen.
Al zal ik de info(tekst,image) gescheiden houden , omdat deze natuurlijk maar een keer voor komt per serie en niet bij alle series ( ik sla releases op)
De genres zou ik idd gescheiden kunnen doen evenals de formats .
maar dat helpt natuurlijk niks aan het oorspronkelijke probleem.