oplossing mySQL voor INTERSECT

Pagina: 1
Acties:

  • maurad3r
  • Registratie: Oktober 2004
  • Laatst online: 20:13
Hey,

Ik heb hier een uur of twee geleden een topic gepost over de opbouw van mijn database, deze is geslaagd: het lukt me echter niet om de juiste gegevens middels een query terug te krijgen.

Ik heb nu dus bij de recensenten wat kenmerken en lievelingsgenre's aan hun naam gehangen. Dit heb ik zo gerealiseerd in mijn database:

code:
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
32
33
34
Recensent
id    recensent
---------------------------------------------------------------
1                     Koen Poolman
2                     Roel vd Ven

genre2recensent
recensent_id      genre_id
-------------------------------------
1                        1
1                        2
2                        3

genre
id         genre
------------------------------
1                    Jazz
2                    Nu-metal
3                    Pop


kenmerk2recensent
recensent_id      kenmerk_id
-------------------------------------
1                        3
2                        2
2                        1

Kenmerk
id         kenmerk
------------------------------
1                    Dood
2                    Bekend
3                    Diskjockey


De bedoeling is dat er nu een pagina komt waarop je kenmerken en genre's kan selecteren: vervolgens gaat hij de passende recensent zoeken. Ik dacht dit te doen door èèn query voor het selecteren van de recensenten die voldoen aan de genre's te intersecten met èèn andere die alle recensenten selecteert die passen bij de opgegeven kenmerken. Dan zou mijn query er dus zo uitgezien hebben ( het getal achter 'having n =', staat voor het aantal opgegeven begrippen waarop gezocht moet worden).

Deze query zou alle recensenten moeten selecteren die Jazz en Nu-metal als lievelingsgenre hebben en die Diskjockey zijn!:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
SELECT recensent, count(  *  )  AS n
FROM recensent AS r, genre2recensent AS g2r
WHERE g2r.recensent_id = r.id  AND ( g2r.genre_id = 1 OR g2r.genre_id = 2 )
GROUP  BY r.id
HAVING n  = 2

INTERSECT

SELECT recensent, count(  *  )  AS n
FROM recensent AS r, kenmerk2recensent AS k2r
WHERE k2r.recensent_id = r.id  AND k2r.genre_id = 3
GROUP  BY r.id
HAVING n  = 1


Nu is het probleem dat MySql voor zover ik weet geen INTERSECT ondersteunt (waar ik ook pas 10s geleden achterkwam :(, al dat werk voor niets). Heeft iemand ook maar enig idee hoe ik deze query anders zou kunnen bouwen!

Alvast bedankt en sorry mocht het niet te volgen zijn!

Verwijderd

Waarom geen simpele doch effectieve JOINs? Join alle tables aan elkaar, zet de juiste where condities, en klaar is klara ...

offtopic:
Ik snap sowieso niet waarom je GROUP BY en HAVING gebruikt hier? En INTERSECT al helemaal niet ...

  • Paul
  • Registratie: September 2000
  • Laatst online: 20:02
Misschien denk ik wel VEEL te simpel, maar:

SQL:
1
2
3
SELECT r.resensent 
FROM recensent r, genre2recensent g, kenmerk2recensent k 
WHERE r.id=g.recensent_id AND r.id=k.recensent_id AND g.genre_id=$genre_id AND k.kenmerk_id=$kenmerk_id;
:?

Edit: wat ^^ hij zegt dus :P

[ Voor 7% gewijzigd door Paul op 16-09-2005 00:35 ]

"Your life is yours alone. Rise up and live it." - Richard Rahl
Rhàshan - Aditu Sunlock


  • maurad3r
  • Registratie: Oktober 2004
  • Laatst online: 20:13
Paul Nieuwkamp schreef op vrijdag 16 september 2005 @ 00:34:
Misschien denk ik wel VEEL te simpel, maar:

SQL:
1
2
3
SELECT r.resensent 
FROM recensent r, genre2recensent g, kenmerk2recensent k 
WHERE r.id=g.recensent_id AND r.id=k.recensent_id AND g.genre_id=$genre_id AND k.kenmerk_id=$kenmerk_id;
:?

Edit: wat ^^ hij zegt dus :P
Zo kan het idd ALS er sprake is van maar één kenmerk en maar één genre:het gaat vrijwel altijd om meerdere genres en/of kenmerken en dan gaat jou query niet op!


denk ik dan

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 15-04 22:07

NMe

Quia Ego Sic Dico.

Dan gebruik je een query waarbij je gebruik maakt van de IN-operator?

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


  • T-MOB
  • Registratie: Maart 2001
  • Laatst online: 22:53
Je kunt dit toch gewoon oplossen met JOINS?
Zoiets zou je kunnen proberen:

code:
1
 Woei dat was een load of crap ;) tijd voor bed...

[ Voor 70% gewijzigd door T-MOB op 16-09-2005 00:51 . Reden: Euh.. ja ]

Regeren is vooruitschuiven


  • Eelke Spaak
  • Registratie: Juni 2001
  • Laatst online: 30-04 10:48

Eelke Spaak

- Vlad -

Als ik goed begrijp wat jouw query doet (met INTERSECT - wat ik niet kende) kan je heel simpel je INTERSECT ook herschrijven naar een WHERE IN (subselect) als je MySQL versie tenminste subselects ondersteunt. Ongetwijfeld kan het ook met joins, maar ik heb even geen tijd om uit te zoeken hoe precies :) .

edit:
Hmm, zie nu dat je groupt, dan wordt het wat lastiger... Iig moet je met dit idee misschien wat verder komen. (NB onderstaande query zal dus niet werken :) )


code:
1
2
3
4
5
6
7
8
9
10
11
12
13
SELECT recensent, count(  *  )  AS n
FROM recensent AS r, genre2recensent AS g2r
WHERE g2r.recensent_id = r.id  AND ( g2r.genre_id = 1 OR g2r.genre_id = 2 )
GROUP  BY r.id
HAVING n  = 2

WHERE r.id IN (

SELECT r2.id
FROM recensent AS r2, kenmerk2recensent AS k2r
WHERE k2r.recensent_id = r.id  AND k2r.genre_id = 3
GROUP  BY r2.id
HAVING n  = 1 )

[ Voor 12% gewijzigd door Eelke Spaak op 16-09-2005 08:27 ]

TheStreme - Share anything with anyone


  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Eelke Spaak schreef op vrijdag 16 september 2005 @ 08:25:
edit:
Hmm, zie nu dat je groupt, dan wordt het wat lastiger... Iig moet je met dit idee misschien wat verder komen. (NB onderstaande query zal dus niet werken :) )
Als je er dan iets als SELECT ... GROUP BY id HAVING COUNT(*) = 1 van maakt zou het nog wel moeten werken ook.

Andere oplossing is het joinen van de subselects, zoiets:
SELECT ... FROM (SELECT id ... eerste query) a JOIN (SELECT id ... tweede query) b ON a.id = b.id

En voor degenen die geen mysql 4.1 hebben kan je de resultaten van die subqueries in temporary tables stoppen en dan de temporary tables aan elkaar joinen.

  • Dido
  • Registratie: Maart 2002
  • Laatst online: 19:47

Dido

heforshe

Maurad3r schreef op vrijdag 16 september 2005 @ 00:42:
Zo kan het idd ALS er sprake is van maar één kenmerk en maar één genre:het gaat vrijwel altijd om meerdere genres en/of kenmerken en dan gaat jou query niet op!


denk ik dan
Datzelfde probleem had je ook in jouw oorspronkelijke query (waar je het m.i. lelijk oplost), diezelfde oplossing kan toch ook in die join-query :?

Wat betekent mijn avatar?


  • maurad3r
  • Registratie: Oktober 2004
  • Laatst online: 20:13
Allemaal bedankt voor de reacties!
Dit was nu al de 2e keer dat ik mysql 4.1 miste ivm subselects, dus ik heb hem maar geinstalleerd.

Nu heb ik het zo opgelost, en dat werkt perfect!
Danku allemaal!

code:
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
SELECT
    r.recensent
FROM
    recensent AS r,
    g2r
WHERE
    g2r.recensent_id = r.id
    AND (
        g2r.genre_id = 1
        OR g2r.genre_id = 2
    )
    AND r.id IN
        (
            SELECT
                r.id
            FROM
                recensent AS r,
                k2r
            WHERE
                k2r.recensent_id = r.id
                AND (
                    k2r.kenmerk_id = 1
                    OR k2r.kenmerk_id = 2
                )
            GROUP BY r.id
            HAVING COUNT(*) = 2
        )
GROUP BY r.id
HAVING COUNT(*) = 2
Pagina: 1