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
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