Avatar billede nemlig Professor
09. juni 2021 - 20:46 Der er 14 kommentarer og
1 løsning

Forespørgsel på felt, der indeholder et array

Hejsa. Jeg har noget PHP-kode, der udfordrer mig.
Jeg har en tabel med et felt (brugerID), hvor der er gemt et array(). Arrayet er gemt med serialize($array) og kan fx. se sådan her ud:
a:4:{i:0;i:72;i:1;i:73;i:2;i:74;i:3;i:75;}
Der er altid tale om hele tal, men arrayet kan have lige fra 0 poster til 30 poster.

Er det muligt at lave en forespørgsel/SELECT, hvor jeg får hentet alle poster, hvor værdien 75 fremgår af arrayet? (i eksemplet ovenfor fremgår værdien 75 i array-post nr. 4.).
Avatar billede arne_v Ekspert
09. juni 2021 - 21:01 #1
SELECT FROM tabel WHERE brugerid LIKE '%i:75;%'
Avatar billede arne_v Ekspert
09. juni 2021 - 21:02 #2
Men overvej en bedre tablstruktur med en separat tabel og en en-til-mange relation.
Avatar billede nemlig Professor
09. juni 2021 - 21:04 #3
Nice - jeg havde slet ikke tænkt i den retning.
Jeg var ude i noget med SELECT FROM tabel WHERE brugerid IN(75), men det fungerede ikke.

Tak for en god og simpel løsning.
Avatar billede erikjacobsen Ekspert
09. juni 2021 - 22:18 #4
...  LIKE '%i:75;%'    vil også finde felter, hvor der står 175, og 275 og 750.  Det er altså næppe en holdbar løsning.
Avatar billede erikjacobsen Ekspert
09. juni 2021 - 22:19 #5
#4 Ok - jeg skulle nok have læst det med småt ... Det kan godt være det isoleret set virker her. Men ikke en go' løsning.
Avatar billede nemlig Professor
09. juni 2021 - 22:23 #6
#5 Det virker, men jeg er stadig modtagelig for gode input ;)
Avatar billede arne_v Ekspert
09. juni 2021 - 22:40 #7
Det virker her fordi der er et fast prefix 'i:' og et fast suffix ';' som forhindrer "forkerte" match.

Men løsningen i #2 er stadig bedre.
Avatar billede acore Ekspert
10. juni 2021 - 01:51 #8
Næsten enig. Det virker dog ikke, hvis index kan være 75, hvilken kun kan ske, hvis index ikke er fortløbende (idet der max er 30 poster).
Avatar billede arne_v Ekspert
10. juni 2021 - 02:08 #9
#8

??
Avatar billede acore Ekspert
10. juni 2021 - 10:04 #10
#9: Åbenbart dårlig forklaring fra min side - prøver med et eksempel:

$a = array(0 => 74, 75 => 76);
echo(serialize($a));

giver

a:2:{i:0;i:74;i:75;i:76;}

og vil dermed være et forkert match med metoden fra #1.

Nu tyder eksemplet fra spørger på, at array index er fortløbende, og i så fald er det ikke et problem. Men i modsat fald eller hvis antallet kan være over 75.

Det var det jeg mente...
Avatar billede nemlig Professor
10. juni 2021 - 11:42 #11
#10. Så fangende jeg også din pointe, og den er faktisk rigtig god :)
Der vil max være 30 poster i arrayet, men den værdi jeg vil tjekke på kan fx være 5 (i stedet for 75), og så har vi "balladen".

Jeg er med på Arnes råd i #2 med at gemme værdierne i en særskilt tabel og joine dem. Og jeg fornemmer nu, at det skal være min løsning, da det andet ikke vil fungere.
Avatar billede acore Ekspert
10. juni 2021 - 12:37 #12
Alternativt skal du lave søgningen i php

if (array_search(75, unserialize($a), true))
... /// then we have a match

på alle rækker i tabellen (ved godt, at du gerne ville lave det i SELECT - men når nu det er svært).
Avatar billede arne_v Ekspert
10. juni 2021 - 14:47 #13
Ah.

Så opgaven er ikke at finde rækker med i:n;  men at finde rækker med i:n; i en lige position (2, 4, 6, ...).

Så duer den simple LIKE ikke.
Avatar billede arne_v Ekspert
10. juni 2021 - 14:56 #14
Mulige løsninger:
1) separat tabel - hvilket er den rigtige løsning ifølge al relationel database teori
2) implementere en UDF som parser den værdi og checker om, værdi er i en lige position
    A) SQL UDF - vil formentlig gøre det til verdens mest langsomme applikation da
        SQL er uegnet til opgaven
    B) UDF i rigtigt programmerings sprog - for MySQL betyder det C, tricky kode og
        fuld adgang til server hvilket ikke lyder tiltalende
3) hente alle rækker og lade applikationen udvælge - det vil formentligt være ret
    nemt, men er et problem med et meget stort antal rækker
4) skift fra serialize til json_encode og hack en LIKE til at virke (med json_encode
    er der forskel på keys og values)
Avatar billede nemlig Professor
10. juni 2021 - 17:27 #15
Super dejligt med jeres løsningsforslag.
Jeg har fået det til at fungere med #14 forslag 4. Jeg er med på, at det ikke er elegant. Løsningen blev:

1. At gemme værdierne i en streng, hvor værdier er omkranset af udråbstegn - sådan her
[!2!,!5!,!7!,!75!]
2. Så kan jeg i min SELECT søge med %!7!%  (og kun fange 7 og ikke 75)

Endnu engang tak for super gode input.
Jeg vælger senere at bruge Arnes #14, 1.
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