Avatar billede lullalej Nybegynder
13. juli 2011 - 21:20 Der er 25 kommentarer og
2 løsninger

Array-søgning i MySQL

Hej

Jeg har en array, $tags, som f.eks. indeholder: script,php,mysql

I min tabel "artikler" i databasen, har jeg et felt der hedder "tags".

Jeg vil søge i databasen, og få vist alle rows hvor tags indeholder et af ordene fra mit array.

Jeg har efterhånden prøvet alt hvad jeg er kunnet komme på, så nu bliver jeg nød til at spørge om hjælp.
Avatar billede kjeldsted Novice
13. juli 2011 - 21:22 #1
Indsæt i søge SQL'en:
WHERE tags LIKE '%$tag%'
Avatar billede lullalej Nybegynder
13. juli 2011 - 21:35 #2
Men så virker det kun hvis de står i den rækkefølge, og de alle sammen er der ;)
Avatar billede jakobdo Ekspert
13. juli 2011 - 21:39 #3
Det er jo også helt forkert at gemme data i et array i mysql.

Du bør jo netop oprette en tabel som hedder tags, som så indeholde en række pr ord:

mysql
script
php
etc...

Og så laver du en tabel, som hedder artikel_tag
I den tabel gemmer du:
artikel_id og tag_id

Så kan du nemmere søge og holde styr på dine tags...
Avatar billede kjeldsted Novice
13. juli 2011 - 21:44 #4
For det første er Jacob's idé ikke helt dum. Desuden ville jeg jo ikke have du skulle søge efter ALLE tag på én gang.
SELECT id FROM tabel WHERE tags LIKE '%$tag1%' OR tags LIKE '%$tag2%' OR LIKE '%$tag3%'
Avatar billede lullalej Nybegynder
13. juli 2011 - 21:47 #5
Men nu er det jo lige sådan her det er bygget op.. Og ville gerne undgå en masse rod som kjeldsted foreslår.

Hvis det var noget jeg selv måtte bestemme 100%, så havde jeg også lavet en tabel med tags ;)

Men der burde være en alternativ metode?
Avatar billede jakobdo Ekspert
13. juli 2011 - 21:52 #6
Så skal du jo lave noget ala:

Del tags op...
Lav en WHERE til hvert tag som kjeldsted er inde på.

Det er dog langt fra optimalt, men åbenbart den løsning du søger.
Avatar billede kjeldsted Novice
13. juli 2011 - 21:55 #7
Altså nu er det jo relativt lidt kode der skal til at splitte et array op i en søgning som #4. Det er ikke simpelt at lave søgefunktioner i SQL.

Umiddelbart vil jeg tro det nemmeste er at loope array'et og lave den om til en streng med format som i #4, hvis ikke du vil lave en tabel til det.
Avatar billede kjeldsted Novice
13. juli 2011 - 21:56 #8
#6: Er det ikke endnu mere tåbeligt? Det må da være bedre med én MySQL query end 15?
Avatar billede jakobdo Ekspert
13. juli 2011 - 22:01 #9
#8 Jeg mener det samme som du foreslår i #4. Så vi er enige. Og jeg skriver jo ikke en query pr tag...
Avatar billede lullalej Nybegynder
13. juli 2011 - 22:02 #10
Men nu var det jo ikke den simple løsning jeg søgte, for lige nu kører det som #4
Avatar billede jakobdo Ekspert
13. juli 2011 - 22:06 #11
#10: Hvad ønsker du så?
Avatar billede lullalej Nybegynder
13. juli 2011 - 22:09 #12
Argh, bare glem det...
Avatar billede kjeldsted Novice
13. juli 2011 - 22:09 #13
#9: Sorry. Selvfølgelig.

#10: Så har jeg da også helt misforstået. Først kalder du det rod og nu for simpelt.
Avatar billede kjeldsted Novice
13. juli 2011 - 22:14 #14
Altså vi vil da gerne hjælpe :)

Og nu bliver jeg nysgerrig. Hvad er det som #4 ikke kan men som den skal kunne?
Avatar billede lullalej Nybegynder
13. juli 2011 - 22:16 #15
Jeg fandt noget i retningen af:

mysql_query("SELECT * FROM artikler WHERE IN tags ('".explode(',',$tags)."')";

Men det virker lidt forkert, og kommer også med en fejl i stedet for.

Men I behøver ikke brugere mere tid på det, jeg finder nok en anden løsning en dag.
Avatar billede jakobdo Ekspert
13. juli 2011 - 22:20 #16
Vi sidder jo ikke her og bruger tid bare for at spilde vores tid. Vi forsøger jo vitterligt at hjælpe.
Men hvis ikke du kan fortælle hvad du vil, så er det jo svært for os.
Vi gør jo udelukkende dette for at lære og for hjælpe.
Avatar billede kjeldsted Novice
13. juli 2011 - 22:23 #17
Som #16 skriver:

Vi gør det for at lære og hjælpe. Og jeg ville nemlig gerne selv blive endnu klogere på dette område.

Men som sagt, hvis ikke du kan beskrive hvad du vil.
Avatar billede lullalej Nybegynder
13. juli 2011 - 22:26 #18
Det er jeg godt klar over at i gør.

Men hvis jeg vidste hvordan jeg skulle forklare det, havde jeg gjort det.
Hvis jeg vidste hvilken funktion jeg skulle bruge, havde jeg bare brugt den.
Avatar billede jakobdo Ekspert
13. juli 2011 - 22:29 #19
Men du har jo fået 2 forslag.

Optimale løsning.
Tag tabel.
Tag_artikel tabel.

Din løsning.
tags = mysql,php,script etc...

Og derfor skal du jo lave "flere" søgninger ala:

where tags LIKE %php% and tags LIKE %mysql% osv...

Kan dog ikke lige tænke om man kunne lave en 3 løsning, med noget subquery.
Avatar billede lullalej Nybegynder
13. juli 2011 - 22:32 #20
Opret svar begge to, så kan i få point.. Vi kommer jo nok ikke videre her.
Avatar billede jakobdo Ekspert
13. juli 2011 - 22:32 #21
Svar!
Avatar billede kjeldsted Novice
13. juli 2011 - 22:48 #22
Svar.
Avatar billede jakobdo Ekspert
14. juli 2011 - 08:24 #23
Takker for point.
Avatar billede kjeldsted Novice
14. juli 2011 - 08:50 #24
Også tak herfra.
Avatar billede vagnk Juniormester
15. juli 2011 - 05:08 #25
Som jeg ser det er der to løsninger:

1.
Løb din array igennem og dan et sql-stmt i retning af:
SELECT id FROM tabel WHERE tags = 'script'
UNION SELECT id FROM tabel WHERE tags = 'php'
UNION SELECT id FROM tabel WHERE tags = 'mysql';

Læg mærke til at det af MySQL bliver opfattet og behandlet som 1 query og du får de rækker tilbage hvor der er hit.

2.
Løb din array igennem og dan en streng $instr der ligner "'script', 'php', 'mysql'";
Derefter SELECT id FROM tabel WHERE tags IN ($instr);
Avatar billede kjeldsted Novice
15. juli 2011 - 08:06 #26
#25:

Du mener vel

SELECT id FROM tabel WHERE tags LIKE '%script%'

i stedet for? Ellers søger del vel kun der hvor det pågældende tag figurer alene.
Avatar billede vagnk Juniormester
15. juli 2011 - 11:47 #27
OK, jeg undrede mig over hvor det LIKE kom fra, men nu kan jeg godt se på lullalejs første svar at der kan være 0-n tags separeret på en eller anden måde i feltet 'tags', og så har du ret og $instr i forslag 2 skal bygges op som "'%script%', ... osv".

Hvis lullalej vil forfine mit forslag 1 kan det gøres med:
SELECT 1 AS sort, 'script' AS tagnam, id FROM tabel WHERE tags LIKE '%script%'
UNION SELECT 2 AS sort, 'php' AS tagnam, id FROM tabel WHERE tags LIKE '%php%'
UNION SELECT 3 AS sort, 'mysql' AS tagnam, id FROM tabel WHERE tags LIKE '%mysql%'
UNION ...
UNION ...
ORDER BY 1;

Men er det så ikke lige før man skulle gå den modsatte vej og hente alle rækker hvor tags IS NOT NULL og så massere tags-feltet med en foreach($tags as ...)?

Det må komme an på hvor mange tags vi taler om i $tags og hvor mange rækker der skal masseres, men nu har han da nogle forslag.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester