SQL Query waar WHERE IN niet voldoet

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Afbeeldingslocatie: http://i40.tinypic.com/2ueqhvs.jpg

SQL die wordt geprobeerd, maar verkeerde output geeft:
SELECT articles.id, words.word FROM articles, words WHERE IN word.word ('wellus', 'nietus')

Functie:
Alle article-id's geven met gekoppeld zowel 'wellus' als 'nietus' in de words-tabel.

Output (zoals die hoort):
2 # heeft wellus, nietus
5 # heeft wellus, nietus

Output (zoals die is):
1 #heeft wellus
2 #heeft wellus
2 #heeft nietus
4 #heeft nietus
5 #heeft wellus
5 #heeft nietus
Hij kijkt of er OF wellus OF anders in staat.
Bij word.word='wellus' AND word.word='nietus' kijkt hij per regel en dan is er geen output

De eerste oplossing leek me 'WHERE IN', maar deze doet precies hetzelfde als word.word='wellus' OR word.word='nietus'.

Acties:
  • 0 Henk 'm!

  • storeman
  • Registratie: April 2004
  • Laatst online: 23:07
Ik denk dat je met subqueries moet werken.

SQL:
1
2
3
4
SELECT articles.id FROM articles 
WHERE 
id IN ( SELECT article_id FROM words WHERE word='wellus') 
AND id IN (SELECT article_id FROM words WHERE word='nietus')


Ik heb het idee dat je een zoekmachine aan het bouwen bent, wellicht kun je hier eens kijken voordat je het wiel opnieuw uitvind ;)

[ Voor 33% gewijzigd door storeman op 13-05-2009 10:11 . Reden: code-tags, extra info ]

"Chaos kan niet uit de hand lopen"


Acties:
  • 0 Henk 'm!

  • justmental
  • Registratie: April 2000
  • Niet online

justmental

my heart, the beat

SQL:
1
2
3
select id from articles
where id in (select article_id from words where word = 'wellus')
and id in (select article_id from words where word = 'nietus')

Who is John Galt?


Acties:
  • 0 Henk 'm!

  • Noork
  • Registratie: Juni 2001
  • Niet online
Ik zie niks in je statement dat een koppeling maakt tussen id uit articles en article_id uit words. Dus doe eerst even een join, subselect of zoiets, anders gaat het niet werken.

Acties:
  • 0 Henk 'm!

  • DamadmOO
  • Registratie: Maart 2005
  • Laatst online: 19-09 19:31
Sowieso ben jij een join vergeten tussen je articles en words tabel dus je resultaat zal je nooit hetgeen oplevern wat je wilt. Verder is de IN clausule in je WHERE gewoon te herschrijven naar een OR (bekijk hiervoor je execution plan).

Ook is hetgeen wat je precies wilt me niet helemaal duidelijk maar hieronder een oplossing voor je probleem:
SQL:
1
2
3
4
SELECT a.id
FROM articles as a
JOIN words as ww on a.id = ww.article_id and ww.word = 'wellus'
JOIN words as wn on a.id = wn.article_id and wn.word = 'nietus'


Of dit ook toepasbaar is voor jou specifieke use-case weet ik niet omdat er gewoon niet genoeg informatie is over hetgeen je precies wilt.

[ Voor 1% gewijzigd door DamadmOO op 13-05-2009 10:10 . Reden: Ok... nu zal het wel duidelijk zijn voor de TS. Ik heb er tenminste nog informatie bij getikt :D ]


Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Je zou het op kunnen lossen met meerdere sub-selects
SQL:
1
2
3
4
SELECT a.*
FROM articles a
WHERE a.id in ( SELECT w.articleId FROM words w WHERE w.word = 'wellus' )
AND a.id in ( SELECT w2.articleId FROM words w2 WHERE w2.word = 'nietus' )


offtopic:
5 reacties binnen een minuut :D

[ Voor 7% gewijzigd door Woy op 13-05-2009 10:09 ]

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • Niemand_Anders
  • Registratie: Juli 2006
  • Laatst online: 09-07-2024

Niemand_Anders

Dat was ik niet..

Omdat je alleen het artikelid's terug wilt hebben kun je ook een group by doen op het article.id met een having count gelijk aan het aantal woorden in je array.

Want de query van bijvoorbeeld justmetal werkt wel, maar is niet leuk als de array 5 of zelfs 30 woorden bevat.

SQL:
1
2
SELECT articles.id FROM articles, words WHERE IN word.word ('wellus', 'nietus') 
GROUP BY articles.id HAVING COUNT(articles.id) = 2

If it isn't broken, fix it until it is..


Acties:
  • 0 Henk 'm!

  • storeman
  • Registratie: April 2004
  • Laatst online: 23:07
DamadmOO schreef op woensdag 13 mei 2009 @ 10:08:
...
SQL:
1
2
3
4
SELECT a.id
FROM articles as a
JOIN words as ww on a.id = ww.article_id and ww.word = 'wellus'
JOIN words as wn on a.id = wn.article_id and wn.word = 'nietus'

....
Wellicht een betere methode dan subqueries, als ik het me goed herinner gebruiken subqueries de indexes niet altijd even goed, terwijl dit met een join perfect gaat.

"Chaos kan niet uit de hand lopen"


Acties:
  • 0 Henk 'm!

  • justmental
  • Registratie: April 2000
  • Niet online

justmental

my heart, the beat

Niemand_Anders schreef op woensdag 13 mei 2009 @ 10:12:
Omdat je alleen het artikelid's terug wilt hebben kun je ook een group by doen op het article.id met een having count gelijk aan het aantal woorden in je array.

Want de query van bijvoorbeeld justmetal werkt wel, maar is niet leuk als de array 5 of zelfs 30 woorden bevat.

SQL:
1
2
SELECT articles.id FROM articles, words WHERE IN word.word ('wellus', 'nietus') 
GROUP BY articles.id HAVING COUNT(articles.id) = 2
Dan neem je wel aan dat er een unique constraint op article_id en word ligt, anders is een dubbele wellus ook waar.

Who is John Galt?


Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
storeman schreef op woensdag 13 mei 2009 @ 10:13:
[...]
Wellicht een betere methode dan subqueries, als ik het me goed herinner gebruiken subqueries de indexes niet altijd even goed, terwijl dit met een join perfect gaat.
Dat kun je niet zo generiek zeggen zonder meer van het RDBMS te weten.
justmental schreef op woensdag 13 mei 2009 @ 10:17:
[...]

Dan neem je wel aan dat er een unique constraint op article_id en word ligt, anders is een dubbele wellus ook waar.
Op article_id zal er wel een unique constraint zijn waarschijnlijk ( hoop ik ), maar op word ligt het inderdaad misschien wel anders.

[ Voor 34% gewijzigd door Woy op 13-05-2009 10:18 ]

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • DamadmOO
  • Registratie: Maart 2005
  • Laatst online: 19-09 19:31
Woy schreef op woensdag 13 mei 2009 @ 10:17:
[...]

Dat kun je niet zo generiek zeggen zonder meer van het RDBMS te weten.
Dat kun je niet eens zeggen als je het RDBMS weet. Binnen één RDBMS kan je zelfs vershillende resultaten krijgen qua performance. Dat ligt voornamelijk aan het data-model en wat de rest van de query doet.

Acties:
  • 0 Henk 'm!

  • winkbrace
  • Registratie: Augustus 2008
  • Laatst online: 24-08 15:17
DamadmOO schreef op woensdag 13 mei 2009 @ 10:21:
[...]

Dat kun je niet eens zeggen als je het RDBMS weet. Binnen één RDBMS kan je zelfs vershillende resultaten krijgen qua performance. Dat ligt voornamelijk aan het data-model en wat de rest van de query doet.
Ik durf er wel wat onder te verwedden dat een JOIN altijd sneller is dan een WHERE .. IN (..)

Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
BazzPsychoNut schreef op woensdag 13 mei 2009 @ 13:56:
[...]
Ik durf er wel wat onder te verwedden dat een JOIN altijd sneller is dan een WHERE .. IN (..)
Die weddenschap durf ik wel aan. Veel RDBM'sen zullen bij sommige JOIN's gewoon precies hetzelfde execution plan gebruiken als WHERE IN.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • justmental
  • Registratie: April 2000
  • Niet online

justmental

my heart, the beat

Als je gaat vergelijken zorg dan dat de query functioneel hetzelfde is. Als er geen unique constraint op 'article_id' en 'word' ligt dan is de join functioneel anders dan de subquery.
Als ze echt hetzelfde zijn zal elk fatsoenlijk rdbms tot hetzelfde executie-plan en dus ook dezelfde performance komen.

Who is John Galt?

Pagina: 1