Eigen movie/film database
ik heb hier thuis een reeks dvd's op mijn pc gebackupt.
Nu wil ik een database (php/sql) maken.
Dit is aardig gelukt en ben relatief te vreden (Ik kan films zoeken enz...)
Maar zit nu met 1 probleem. Een film zoeken op titel (in een tabel) is geen enkel probleem... Maar nu wil ik op genre kunnen zoeken, en liefst soms nog op 2 genres.
Mijn database ziet er als volgt uit:
3 tabellen: Films, genre, film_genre
Hoe moet ik nu bijvoorbeeld alle films selecteren die zowel tot het genre: Horror als tot het genre Actie behoren ZONDER dat ik sommige resultaten 2 keer krijg?
Ik weet niet meer juist wat ik destijds geprobeerd heb, maar toen kreeg ik alle "horror" films EN alle "actie" films...
Alvast bedankt
Code (php)
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
SELECT DISTINCT f.film_titel
FROM film AS f
LEFT JOIN film_genre AS fg
ON (fg.film_id = f.id)
LEFT JOIN genre AS g
ON (g.id = fg.genre_id)
WHERE g.genre LIKE '%oorlog'
OR g.genre LIKE '%actie%'
GROUP BY g.genre_id
ORDER BY f.film_titel DESC
FROM film AS f
LEFT JOIN film_genre AS fg
ON (fg.film_id = f.id)
LEFT JOIN genre AS g
ON (g.id = fg.genre_id)
WHERE g.genre LIKE '%oorlog'
OR g.genre LIKE '%actie%'
GROUP BY g.genre_id
ORDER BY f.film_titel DESC
Probeer eens...
Gewijzigd op 05/08/2012 14:27:19 door Eddy E
http://www.phphulp.nl/php/forum/topic/ongelooflijk-trage-queries-met-zf/85836/2/
De laatste post van Ger zou een werkende oplossing moeten geven (getest door hem en mij) en ook nog eens een efficiente.
Eddy Erkelens op 05/08/2012 14:22:29:
Zal ik is proberen...
Erwin H op 05/08/2012 14:30:10:
Hoewel de vraag in eerste instantie heel anders was, gaat het om een identiek probleem:
http://www.phphulp.nl/php/forum/topic/ongelooflijk-trage-queries-met-zf/85836/2/
De laatste post van Ger zou een werkende oplossing moeten geven (getest door hem en mij) en ook nog eens een efficiente.
http://www.phphulp.nl/php/forum/topic/ongelooflijk-trage-queries-met-zf/85836/2/
De laatste post van Ger zou een werkende oplossing moeten geven (getest door hem en mij) en ook nog eens een efficiente.
Als het eerder geschreven gedeelte niet lukt, zal ik dit is bekijken.
Alvast bedankt.
Btw, maakt niet uit dat ik een secondje langer moet wachten. Het is een volledig offline database die wss enkel ik of de mensen hier lokaal, gebruik van zullen maken. Als het maar werkt :D
Ik denk dat die van Eddy wel werkt, maar het is in principe een foute query. GROUP BY kan je eigenlijk niet gebruiken als je geen aggregate functie gebruikt. Ik weet dat veel mensen daar een broertje aan dood hebben, maar het werkt dus alleen bij de gratie van de database server....
Code (php)
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
SELECT DISTINCT f.film_titel
FROM film AS f
LEFT JOIN film_genre AS fg
ON (fg.film_id = f.id)
LEFT JOIN genre AS g
ON (g.id = fg.genre_id)
WHERE g.genre LIKE '%oorlog'
OR g.genre LIKE '%actie%'
GROUP BY g.genre_id
ORDER BY f.film_titel DESC
FROM film AS f
LEFT JOIN film_genre AS fg
ON (fg.film_id = f.id)
LEFT JOIN genre AS g
ON (g.id = fg.genre_id)
WHERE g.genre LIKE '%oorlog'
OR g.genre LIKE '%actie%'
GROUP BY g.genre_id
ORDER BY f.film_titel DESC
niet echt aan de praat... 1 genre lukte wel, maar vanaf ik een 2de toevoegde, gaf hij 0 resultaten terug...
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
SELECT F.titel, COUNT(*) AS cnt
FROM film_genre FG
INNER JOIN film F
ON F.id = FG.film_id
INNER JOIN ( SELECT id
FROM genre G
WHERE G.genre = 'horror' OR G.genre = 'actie') SG
ON FG.genre_id = SG.id
GROUP BY FG.film_id
HAVING cnt = (SELECT COUNT(*) test
FROM genre G
WHERE G.genre = 'horror' OR G.genre = 'actie')
FROM film_genre FG
INNER JOIN film F
ON F.id = FG.film_id
INNER JOIN ( SELECT id
FROM genre G
WHERE G.genre = 'horror' OR G.genre = 'actie') SG
ON FG.genre_id = SG.id
GROUP BY FG.film_id
HAVING cnt = (SELECT COUNT(*) test
FROM genre G
WHERE G.genre = 'horror' OR G.genre = 'actie')
Dit werkt op basis van count. Ik heb alleen het idee dat dit ook foute resultaten kan opleveren maar zo even geen situatie bedenken om te testen.
Maar kan je niet gewoon gebruik maken van UNIQ?
Uhm, conclusie laat ik aan jou.... maar UNIQUE (niet UNIQ) heeft hier totaal niets, maar dan ook niets mee te maken. Dat gebruik je bij het creeeren van een index.
Dat is dat je geen dubbele records wilt zien.
Mocht je niet van die GROUP BY houden, verwijder dan eens gewoon. Zelf een beetje spelen zou geen kwaad kunnen hoor.
Wat jij nu wilt is hetzelfde als ik op mijn website heb:
www.zunflappie.nl/foto/
Kijk even rond en selecteer iets. Als je bijvoorbeeld 'wielen' selecteert moet je alleen wiel-gerelateerde foto's krijgen. Als je 517 (= met spaakwielen) selecteerd, krijg je alleen die.
Als je de 530 selecteer krijg je gegoten wielen.
Nu kan het best zijn dat een aantal foto's verkeerd getagd zijn hoor.
Maar onderstaande code gebruik ik als opbouw van de query:
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
26
27
28
29
30
31
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<?php
// SQL BOUWEN (eerst WHERE-ding))
foreach($_SESSION['tags'] as $key => $val)
{
if(substr($key, 0, 6) == 'tagid_')
{
$where_array[] = 'tagid = '.intval(substr($key, 6));
}
}
if(empty($where_array)){$where_array[] = 'tagid = 2';}
$aantal_where = count($where_array);
if($aantal_where == 1)
{
$where = $where_array[0];
}
else
{
$where = implode(" OR ", $where_array);
}
// sql uitvoeren en fetchen etc
$sql = "SELECT foto, tagid, COUNT(foto) AS aantal
FROM zun_foto
WHERE ".$where."
GROUP BY foto
HAVING aantal = ".$aantal_where."
ORDER BY foto ASC";
?>
// SQL BOUWEN (eerst WHERE-ding))
foreach($_SESSION['tags'] as $key => $val)
{
if(substr($key, 0, 6) == 'tagid_')
{
$where_array[] = 'tagid = '.intval(substr($key, 6));
}
}
if(empty($where_array)){$where_array[] = 'tagid = 2';}
$aantal_where = count($where_array);
if($aantal_where == 1)
{
$where = $where_array[0];
}
else
{
$where = implode(" OR ", $where_array);
}
// sql uitvoeren en fetchen etc
$sql = "SELECT foto, tagid, COUNT(foto) AS aantal
FROM zun_foto
WHERE ".$where."
GROUP BY foto
HAVING aantal = ".$aantal_where."
ORDER BY foto ASC";
?>
Gewijzigd op 05/08/2012 16:04:00 door Eddy E
Wat jij hier post kan nooit kloppen:
Code (php)
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
SELECT DISTINCT f.film_titel
FROM film AS f
LEFT JOIN film_genre AS fg
ON (fg.film_id = f.id)
LEFT JOIN genre AS g
ON (g.id = fg.genre_id)
WHERE g.genre LIKE '%oorlog'
OR g.genre LIKE '%actie%'
GROUP BY g.genre_id
ORDER BY f.film_titel DESC
FROM film AS f
LEFT JOIN film_genre AS fg
ON (fg.film_id = f.id)
LEFT JOIN genre AS g
ON (g.id = fg.genre_id)
WHERE g.genre LIKE '%oorlog'
OR g.genre LIKE '%actie%'
GROUP BY g.genre_id
ORDER BY f.film_titel DESC
Je joined genre twee keer. Een keer als g en een keer als fg. vervolgens selecteer je de records die g.genre 'oorlog' hebben of die g.genre 'actie' hebben. Hiermee selecteer je DUS NIET de films die BEIDE hebben. Als je dat wilt doen moet je g.genre gelijk zetten aan 'oorlog' en (AND dus) fg.genre gelijk aan 'actie'.
Quote:
Hoe moet ik nu bijvoorbeeld alle films selecteren die zowel tot het genre: Horror als tot het genre Actie behoren ZONDER dat ik sommige resultaten 2 keer krijg?
(bold is mijn toevoeging)
Gewijzigd op 05/08/2012 16:13:33 door Erwin H