SQL Query ,JOIN & MAX

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Paolo Mulder

Paolo Mulder

10/10/2008 10:51:00
Quote Anchor link
Hoi web architecten ,

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 ;)
 
PHP hulp

PHP hulp

25/04/2024 10:35:59
 
Joren de Wit

Joren de Wit

10/10/2008 11:47:00
Quote Anchor link
Allereerst zijn de queries die je nu gebruikt ongeldig, je gebruikt de GROUP BY clausule namelijk op een verkeerde manier! Zie ook 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.
 
Paolo Mulder

Paolo Mulder

10/10/2008 12:20:00
Quote Anchor link
Daar heb ik vrij weinig aan.
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?
 
Joren de Wit

Joren de Wit

10/10/2008 12:46:00
Quote Anchor link
In een geldige GROUP BY clausule zul je alle kolommen op moeten nemen die in de SELECT voorkomen en geen onderdeel zijn van een aggregate functie zoals bijvoorbeeld MAX(). In jouw queries doe je dat niet waardoor de resultaten niet betrouwbaar zijn (zie ook die tutorial waarom niet).

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)
PHP script in nieuw venster Selecteer het PHP script
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
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


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.
 
Paolo Mulder

Paolo Mulder

10/10/2008 18:10:00
Quote Anchor link
Dank voor het wijzen naar de goede weg.

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.
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.