Avatar billede BTEngineer Novice
17. september 2015 - 15:49 Der er 30 kommentarer og
1 løsning

Query find_in_set PHP/MySQL

Hej Eksperter

Jeg har en search query, som jeg ikke kan få til at virke optimal:

$query = 'SELECT id, navn, afdeling, underafdeling, area FROM mydatabase WHERE underafdeling LIKE "'.$search_string.'%" OR FIND_IN_SET('$search_string' ,REPLACE(area, ';', ',') ) AND navn = "'.$navn.'" GROUP BY (afdeling) ORDER BY afdeling LIMIT 9';

Alt virker fint, indtil at jeg tilføjede FIND_IN_SET(), som skal sørge for at sammenligne indholdet af $search_string med den værdi som der er i AREA kolonnen i databasen.

AREA kolonnen indeholder en masse tekststrenge separaret med semi-kolon;

Er der nogen der kan sige mig, hvorfor ovenstående ikke fungerer?

Tak på forhånd!

Mvh
Henrik
Avatar billede BTEngineer Novice
17. september 2015 - 21:42 #1
Spørg endelig!

I må også meget gerne komme med alternative løsninger! :)
Avatar billede BTEngineer Novice
19. september 2015 - 09:07 #2
Anyone?:-)
19. september 2015 - 10:55 #3
Vi har aftalt andetsteds, at jeg skulle prøve at hjælpe her.  Men jeg er ikke sikker på, at jeg kan gennemskue det.  Lad mig se, om jeg forstår problemstillingen.  Du har du har tekststrenge i underafdeling, og i area har du adskillige tekststrege.  Du søger med to variabler, $search_string og $navn, og du vil have data udskrevet hvis $navn matcher og enten $search_string matcher i underafdeling eller findes i area.  Er det korrekt forstået?

Så siger du, at alt virker fint indtil du tilføjer FIND_IN_SET...  Så med queryen

$query = 'SELECT id, navn, afdeling, underafdeling, area FROM mydatabase WHERE underafdeling LIKE "'.$search_string.'%" AND navn = "'.$navn.'" GROUP BY (afdeling) ORDER BY afdeling LIMIT 9';

får du værdierne korrekt udskrevet hvis $navn matcher og $search_string matcher i underafdeling.

Hvad sker der så når du tilføjer FIND_IN_SET...?  Hvis $search_string matcher i underafdeling burde du stadig få dataerne udskrevet, fordi FIND_IN_SET er en OR condition.  Får du det i så fald korrekt udskrevet, eller hvad sker der?  Du har vel prøvet denne query, hvor du ved, at $search_string findes i area:

'SELECT id, navn, afdeling, underafdeling, area FROM mydatabase WHERE FIND_IN_SET('$search_string' ,REPLACE(area, ';', ',') ) '

Hvad sker der så?

Og så var det ikke det du spurgte om, men en datastruktur hvor du har adskillige elementer i et felt i tabellen synes ikke at være optimal.  Hvor kommer indholdet af area feltet fra?  Er der ikke mulighed for i stedet at gemme elementerne i en særskilt tabel?
Avatar billede BTEngineer Novice
19. september 2015 - 11:23 #4
Tak for svar! :)

Følgende fejl vises, når querien køres: Parse error: syntax error, unexpected ',' in

Se eksempel på databasestrukturen her: http://tinypic.com/r/wkpmr6/8

Mht. navn og underafdeling skal du ikke tænke på det. Dét virker som det skal. Problemet er, at jeg gerne vil have $search_string til at lede efter matches i BÅDE underafdeling og area kolonnerne. Og i area kolonnen, skal der kigges på værdier separat fra semi-kolon.

Det var selvfølgelig muligt at gemme værdierne i en særskilt tabel. Men så ville de skulle oprettes hver i sær, med reference til den tilknyttede afdeling. Det ville tage meget lang tid.. Kan ikke lige gennemskue alternativet, må jeg indrømme.

Håber det gav mere brugbar info.
19. september 2015 - 14:10 #5
Unexpected ',' - jamen så må du jo lede efter hvor dette komma kommer ind.  Der forekommer vel ikke komma i variabelen $search_string?  For så virker FIND_IN_SET ikke ifølge https://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_find-in-set .

Jeg noterer mig, at du har mellemrum mellem '$search_string' og kommaet i '$search_string' ,REPLACE(....  Måske er det ikke tilladt og det skal være '$search_string', REPLACE(....

Ellers må du vel gå trin for trin.  Hvad jeg måske ville gøre var først at lave en test tabel med et par værdier hvor strengene i area er adskildt med kommaer og så prøve

SELECT id, navn, afdeling, underafdeling FROM mydatabase WHERE FIND_IN_SET('Arrangementer', area)

og se om du der får fejl.  Hvis ikke, så prøv med din live tabel

SELECT id, navn, afdeling, underafdeling FROM mydatabase WHERE FIND_IN_SET('$search_string' ,REPLACE(area, ';', ',') )

o.s.v.

Hvis du vil have værdierne i area i en særskilt tabel behøver du ikke lave en tabel for hver afdeling.  Det findes der meget nemmere løsninger på, og så vidt jeg kan se, i stedet for at tage mere tid vil det spare dig tid, fordi du kun skal skrive hver værdi et sted i stedet for, som i din eksempel tabel, at du for hver borgerafdeling skal skrive 'Beredskab og akut hjælp; Bolig og byggeri; Familie, ......'  Det kunne blive et emne for et særskilt spørgsmål hvis du har interesse.
19. september 2015 - 14:12 #6
Hvad jeg ville have sagt som trin to var

SELECT id, navn, afdeling, underafdeling FROM mydatabase WHERE FIND_IN_SET('Arrangementer' ,REPLACE(area, ';', ',') )

for at teste om det går godt med at erstatte simekolonnerne med kommaer, og først detefter teste det med en variabel.
Avatar billede BTEngineer Novice
21. september 2015 - 11:43 #7
Hej.

Jeg har afprøvet følgende i en "prøvetabel":

$variable = "Test";

$query = mysql_query("SELECT * FROM test WHERE FIND_IN_SET('$variable' ,REPLACE(area, ';', ',')) ");

$vis = mysql_fetch_array($query);

$antal = mysql_num_rows($query);
    echo $vis['area']."- Antal:".$antal;

Min database indeholder kolonnerne: id, area

id = 1
area = Test;test2;test3

Resultatet af ovenstående query er:
Test;test2;test3- Antal:1

Hvis jeg ændre $variable til andet end Test;test2;test3, er siden blank :)

Men den skal egentlig kun udskrive den værdi den har fundet. Men det er fint at den kigger på dem "separeret". Men jeg er stadig ikke klar over, hvad fejlen er i den anden query.
21. september 2015 - 16:23 #8
1.  Så FIND_IN_SET virker.  Hvis din test tabel kun indeholder værdier der indeholder 'test' vil der naturligvis ikke komme noget resultat med en $variable med andet end 'test'. 

2.  Så må du jo tage næste trin, at udvide din test tabel med underafdeling og måske have fire rækker i tabellen, en hvor underafdeling er 'test' og afdeling er 'test;test2;test3', en hvor underafdeling er noget andet og afdeling er 'test;test2;test3', en hvor underafdeling er 'test' og afdeling er noget andet, og en hvor både underafdeling og afdeling ikke indeholder noget med 'test', lave $search_string = 'test', og køre

$query = 'SELECT * FROM  WHERE underafdeling LIKE "'.$search_string.'%" OR FIND_IN_SET('$search_string' ,REPLACE(area, ';', ',') ) GROUP BY (afdeling) ORDER BY afdeling LIMIT 9';

og se om det stadig går godt.  Og så køre videre trin for trin indtil det ikke længere går godt.
Avatar billede BTEngineer Novice
01. oktober 2015 - 17:14 #9
Hej Christian

Beklager min svartid, men der kom pludselig en rejse med arbejde og sygdom, som jeg måtte tage mig af..

Hvis min area område indeholder følgende: Test;test2;test3;Range;Hej

Udskrives:
Test;test2;test3;Range;Hej- Antal:1

Koden:
include("likes/connect.php");

$variable = "Test";

$query = mysql_query("SELECT * FROM test WHERE FIND_IN_SET('$variable' ,REPLACE(area, ';', ',')) ");

$vis = mysql_fetch_array($query);

$antal = mysql_num_rows($query);
echo $vis['area']."- Antal:".$antal;

Deraf forstår jeg ikke, hvorfor "Range" bliver udskrevet.

Den skal jo finde de resultater som minder om ordet "Test", da det skal anvendes i en søgefunktion. Hvordan gør jeg så det?

Beklager igen at jeg ikke har vendt tilbage før.
Avatar billede BTEngineer Novice
04. oktober 2015 - 14:31 #10
Hej igen,

Jeg har prøvet følgende nu:

$query = "SELECT * FROM offentligeinstitutioner WHERE underafdeling LIKE '$search_string' OR FIND_IN_SET('$search_string' ,REPLACE(area, ';', ',')) AND navn = '$navn' GROUP BY (afdeling) ORDER BY afdeling LIMIT 9";

Dette giver ingen fejl! :) - Det er fremgang!

Men jeg får ingen resultater.. Synes ellers det ser rigtigt ud.

Nogle idéer?
Avatar billede BTEngineer Novice
04. oktober 2015 - 14:41 #11
Spændende! Det virker nu! :)

Koden blev:

$query = "SELECT id,navn,afdeling,underafdeling,area FROM offentligeinstitutioner WHERE underafdeling LIKE '$search_string%' OR FIND_IN_SET('$search_string' ,REPLACE(area, ';', ',')) AND navn = '$navn' GROUP BY (afdeling) ORDER BY afdeling LIMIT 9";

Mit eneste problem nu er, at jeg ønsker at udskrive den specifikke værdi, som der er matchet i kolonnen area. Den udskriver hele area rækken med værdier.

Lige nu ser det således ud:
$display_function = $result['afdeling']." - ".$afdeling1." ".$result['area'];

Og så udskriver den som sagt afdeling og afdeling1 fint, men area udskriver mange værdier.

Nogle forslag?
04. oktober 2015 - 18:16 #12
dounie, nu er det mig der har været på ferie.  Jeg er lige kommet hjem.  Jeg kikker på dine indlæg i morgen.
Avatar billede BTEngineer Novice
04. oktober 2015 - 18:56 #13
Haha, det er helt i orden! :-)

Håber det var en god ferie.

Tak for din hjælp
Avatar billede BTEngineer Novice
07. oktober 2015 - 09:41 #14
Har du nogle idéer til hvordan jeg udskriver den enkelte "area", så ikke hele kolonens indhold udskrives. Det ser lidt tosset ud ;-)
07. oktober 2015 - 23:32 #15
Din query er 'SELECT ....... area FROM .....
så naturligvis udskriver den area, altså hele feltet.  Hvis du vil noget andet må du søge efter noget andet.

Nu står det mig ikke helt klart hvad du vil have udskrevet.  Hvis du i tabellen har en række hvor for eksempel underafdeling er 'aaa' og area er 'bbb; ccc; ddd' og $search_string er 'bbb', så vil rækken blive selected.  Så vil du formentligt ikke have udskrevet area feltet men alene 'bbb'.  Men hvis $search_string er 'aaa' vil rækken også blive selected, fordi det matcher med underafdeling.  Hvad vil du i det tilfælde have udskrevet som area?  'aaa' eller NULL eller ingenting?
Avatar billede BTEngineer Novice
08. oktober 2015 - 07:24 #16
Ja det er korrekt at bbb bliver selected. Men hvordan udskriver jeg så den specifikke værdi? Altså bbb. For når jeg udskriver area kommer alle værdier jo. Så mit problem er at den ikke udskriver én specifik værdi.

Den må gerne udskrive flere resultater. Problemet er bare at den uanset hvad udskriver hele area feltet.
08. oktober 2015 - 08:01 #17
Du svarede ikke på hele spørgsmålet.  Hvis $search_string er 'aaa', en værdi der ikke indgår i area men som er lig med underafdeling, hvad skal der så udskrives for area?  Det er vigtigt at vide hvad du har tænkt dig i dette tilfælde.
Avatar billede BTEngineer Novice
08. oktober 2015 - 08:21 #18
Hov beklager.

Så udskriver den bare underafdeling :)
08. oktober 2015 - 09:43 #19
Vi miskommunikerede en gang mere.  Din query er nu 'SELECT .... underafdeling, area FROM .....' Lad os antage, at din query resulterer i for eksempel ti matches, nogle hvor underafdelingen er lig med search strengen og nogle hvor search strengen forekommer i area, så vil resultatet nu for hver af de ti matches udskrive underafdelingen og hele area, det vil sige også i tilfælde af at search strengen forekommer i underafdelingen men ikke i area.

Nu vil du have noget andet end hele area udskrevet.  Men du skal stadig for hver match have et eller andet udskrevet for area.  Query resultater kommer, som du ved, i tabel form.  Hvis search strengen forekommer i area, så vil du have search strengen udskrevet.  Hvis search strengen ikke forekommer i area, så kan du enten få 'NULL' udskrevet eller '' (blank) eller 'Klodshans' eller ....  Jeg går nu ud fra, at du vil have ''.

I så fald antager jeg (ikke testet), at en kode som det følgende vil give det ønskede resultat:

$query = "SELECT id,navn,afdeling,underafdeling,
IF (FIND_IN_SET('$search_string' ,REPLACE(area, ';', ',')), '$search_string', '') 
FROM offentligeinstitutioner WHERE underafdeling LIKE '$search_string%' OR FIND_IN_SET('$search_string' ,REPLACE(area, ';', ',')) AND navn = '$navn' GROUP BY (afdeling) ORDER BY afdeling LIMIT 9";
Avatar billede BTEngineer Novice
08. oktober 2015 - 13:53 #20
Ja, tror jeg også vi gjorde.

Jeg forstår hvad du skriver.

Jeg kan se nu, at den tilsyneladende ikke engang søger i area.. Den viser i hvert fald ikke resultater den burde gøre.

Nu får du lige real info, så du ligesom kan se hvad det drejer sig om. Det er det letteste. Du får et billede af databasestrukturen og link til siden.

Siden:
http://tinyurl.com/ntwbj8f

Database: (overordnet)
http://i60.tinypic.com/2hncpp1.png

Specifik "area" indhold på én af rækkerne:
http://i58.tinypic.com/2ecp4qo.png

Koden der er på websiden nu, er den du har skrevet i sidste indlæg. Jeg troede den søgte i "area", fordi jeg prøvede med "Moms" osv. Men det matchede jo også underafdelingerne.. Derfor der kom resultat. Det har ikke noget at gøre med "area".. Så det virker vidst ikke rigtig. For hvis du søger efter en specifik area-værdi, som ikke har noget tilfælles med en underafdelingen, så kommer der ingen resultater.

Håber det er til at forstå.
Avatar billede BTEngineer Novice
08. oktober 2015 - 17:42 #21
Hej igen,

Nu skrev jeg noget vrøvl. Koden som jeg havde før den du skrev, virkede når man søgte på de specifikke værdier i areas. Det er den jeg har sat i funktion nu. Så det virker som det skal med den kode..

Problemet er bare, at den viser alle værdierne i area, som jeg har påpeget tidligere. Ellers virker det som det skal.
Avatar billede BTEngineer Novice
08. oktober 2015 - 18:51 #22
Jeg troede det virkede som det skal. Nu har jeg lige gennemtestet det. Det er fordi af den leder i UNDERAFDELING med $search_string%, så den kigger efter hvert enkelt ord i Underafdeling.

Hvis man finder noget som overhovedet ikke matcher med UNDERAFDELING, f.eks. "Gæld (restance)", så kommer der ingen resultater. Selvom dette findes i AREA. Det er din kode der er aktuel lige nu i scriptet.

Beklager de mange kommentarer og evt. forvirring.
09. oktober 2015 - 11:20 #23
Det er mystisk.  Jeg forstod fra #11, at koden virkede, men at du ønskede at ændre den så ikke hele indholdet af area blev vist.  Jeg foreslog så at erstatte 'SELECT ..... area...' med 'SELECT .... FIND_IN_SET.....' og ellers uændret kode.  Du siger så, at hvis searchstrengen findes i area men ikke i underafdeling vises der ingen resultater.

Hvis du går tilbage til den kode du viste in #11, får du så resultater med en searchstreng der findes i area men ikke i underafdeling?
Avatar billede BTEngineer Novice
09. oktober 2015 - 11:38 #24
Det er din kode der er aktiveret nu.

Tror jeg forstår det nu. Hvis du søger: "Satser", så kommer der et result frem. (Dog vises $result['area'] ikke? Altså resultatet). Den skulle jo faktisk gerne vise "Satser". Men det skal jo fungerer sådan, at den søger $search_string% i FIND_IN_SET, ellers skal man søge nøjagtigt det som svarer til en værdi i area. Jeg mener hvis man søger "Satse", må det gerne foreslå "Satser". Den må jo godt vise f.eks. 3 lignende resultater. Problemet er bare at så skal area explodes ";" fra semi-kolon og det er kun de lignende værdier der må vises? De skal jo ikke vises Resultat1;Resultat24;Resultat54, men:
Resultat1
Resultat24
Resultat54


Hvis du søger efter: "Arbejdsmarkedsbidrag (AM-bidrag)" eller "Gæld (restance)", så kommer der ingen resultater. Her begynder jeg så at tro, at den ikke vil accepterer værdier der indeholder tegn såsom f.eks. en parentes. Alle andre værdier finder den resultater på.

Håber det giver mening for dig nu.

Koden virker "delvist" :-D

God weekend til dig
09. oktober 2015 - 11:52 #25
Det vil du ikke svare på?  Mit spørgsmål var (og det er essentielt for at forstå problemet) om den kode du i #11 sagde virkede, om den viste resultater, hvis søgestrengen forekom i area men ikke i underafdeling.  Hvis du i #11 tog fejl og den ikke virkede i disse tilfælde, så er det den kode vi først skal tilbage til og få til at virke.  Så prøv lige at skifte 'min kode' ud med den kode du viste i #11 og undersøg, om de problemer du nu har eksisterede allerede ved den kode, eller om alt virker efter hensigt med den kode (bortset fra at der vises hele indholdet fra area.)  Vi er nødt til at kommunikere, ellers kommer vi ikke videre.  Altså, gå venligst tilbage til før min kode og se om du så får de rigtige resultater.
Avatar billede BTEngineer Novice
09. oktober 2015 - 14:25 #26
Beklager, synes at jeg svarede på det :)

Men svaret er: Ja, den viser resultater, koden i #11, selvom søgestrengen ikke forekommer i underafdeling. Og omvendt hvis søgestrengen forekommer i underafdeling men ikke i area. Og hvis den forekommer i begge, virker det også. Men IKKE når der er parenteser i søgestrengen.. og garanteret heller ikke andre tegn.

Din kode virker på samme måde som #11. Jeg kan ikke se nogle funktionsmæssige ændringer. Udover at $result['area'] værdierne ikke vises i din kode. Der vises intet fra area.

Din kode er den der er aktiv på siden pt.

Håber vi forstår hinanden nu :-)
Avatar billede BTEngineer Novice
19. oktober 2015 - 10:44 #27
Nogen idéer?

// Henrik
Avatar billede BTEngineer Novice
23. oktober 2015 - 19:26 #28
Nu har jeg løst det. Det virker som jeg vil have.

Der er dog én lille ting. Jeg ønsker at gøre sådan, at søgemaskinen kommer frem med forslag der minder om det man har skrevet. Dvs. en funktion som LIKE '$variabel%'. Dvs. skriver jeg satse og der er et result der hedder 'satser', så udskriver den denne værdi.

Nogle idéer til hvordan det kan løses?

Den nuværende query er:
$query = "SELECT id,navn,afdeling,underafdeling,
IF (FIND_IN_SET('$search_string' ,REPLACE(area, ';', ',')), '$search_string', '') AS selectedAreas
FROM offentligeinstitutioner WHERE navn = '$navn' AND underafdeling LIKE '$search_string%' OR FIND_IN_SET('$search_string' ,REPLACE(area, ';', ',')) GROUP BY (afdeling) ORDER BY afdeling LIMIT 9";
24. oktober 2015 - 12:56 #29
dounie, ja, jeg har været længe om at reagere.  Så er det godt, at du i mellemtiden selv har fået det løst.

Nu stiller du et nyt problem op, søgeforslag undervejs.  Det synes jeg er en god ide for dit formål.  Selv kender jeg ikke ret meget til den slags, og jeg vil tro, at det efterhånden kun er mig der kikker på denne tråd. Du bør oplagt, for dette, oprette et nyt frisk spørgsmål der så vil blive set af alle, og så lukke dette spørgsmål (vel nok med eget svar.)  Det er generelt en god ide og mest effektivt at oprette nye spørgsmål for nye problemer.
Avatar billede BTEngineer Novice
24. oktober 2015 - 18:28 #30
Jeg opretter et nyt indlæg til det :)

Smid et svar. Du hjalp mig meget på vej, så du har bestemt ret til at få et accepteret svar.

Tak for hjælpen og god weekend.
24. oktober 2015 - 19:15 #31
Ok.
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
Kategori
Computerworld tilbyder specialiserede kurser i database-management

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



IT-JOB

MAN Energy Solutions

Full Stack Developer

Udviklings- og Forenklingsstyrelsen

Karrieremulighed inden for cybersikkerhed

Cognizant Technology Solutions Denmark ApS

Sr. Test Analyst