Visualizzazione dei risultati da 1 a 8 su 8
  1. #1

    mysql, cercare uno o più valori in un campo testo tra valori separate da virgola

    Saluti a tutti, avrei bisogno di un suggerimento.

    un form di ricerca manda una string contenente uno o più valori separati da una virgola (tipica struttura restituita dopo la selezione di una serie di checkbox: "a,z,c,r"). Nello specifico si tratta di codici associati alle lingue ("en-GB,fr,it"). Questa string viene mandata a uno script php che deve sondare ogni campo 'lingue_parlate' (varchar(40)) di una tabella 'accounts' e controllare se uno o più valori contenuti in questa string e separati da una virgola si trovano nel campo dedicato alle lingue parlate dall'utente associato ad ogni account. Le lingue parlate dall'utente sono registrate in un campo testo sotto questa forma: "fr,it,ru" (ad esempio). Infine lo script seleziona gli utenti che parlano una almeno delle lingue selezionate nel form.
    Sebbene poco sexy, il mio script php finora funziona relativamente bene se una sola lingua deve essere individuata.
    codice:
    	
    // finora lo script riceve il codice di una lingua soltanto
    
    $lingua_cercata = "it";
    	
    // in un while dopo un select globale nella tabella 'accounts' recupero il valore di ogni campo 'lingue_parlate' e creo un array con i codici in esso contenuti:
    	
    
    $lingue_parlate_array = explode(",",$lingue_parlate);	
    $lingue_parlate_count = count($lingue_parlate_array);
    
    for ($j = 0 ; $j < $lingue_parlate_count ; $j++) { 
    	
      if ($lingua_cercata == $lingue_parlate_array[$j]) { 
        $boolLinguaParlata=true;
      } 
    
    }
    Ma se volessi fare la stessa ricerca non più con una sola lingua ma due o più lingue, e quindi con un parametro del tipo:

    codice:
    $lingue_cercate  = "fr,it,ru"     ?
    Ogni suggerimento è il benvenuto. Grazie mille.
    Tancrede

  2. #2
    Utente di HTML.it
    Registrato dal
    Jan 2011
    Messaggi
    1,469
    ... (like '%fr,%') or like ('%it,%') or like ('%ru,%')

    attenzione a due aspetti
    1) ti conviene codificare sempre e comunque con la , finale (per evitare malriconoscimenti di sottostringhe
    2) se invece non ci sono sottostringhe ti basta like '%fr%'

  3. #3
    fammi capire

    vorresti cercare le corrispondenze (ad esempio) tra

    lingue_parlate="it,fr"
    e
    lingue_disponibili="it,es,pt,fr,ru"

    ??? giusto?

  4. #4
    @franzauser grazie, il tuo suggerimento mi è stato molto utile.

    @optime, sì, è esatto, voglio sapere se una o più delle lingue_selezionate="it,es,pt" sono parlate da una o più persone (persona1: lingue_parlate="it,fr" ; persona2: lingue_parlate="ru,pt,en-GB" ; ecc..) Stavo pensando ad una tabella join languages_users (language_id,user_id)

    Mi gioverebbe una soluzione efficace e veloce perché il database è grosso. Intanto riporto qui la soluzione che userò temporaneamente, che però non è molto efficace quando si deve cercare tra moltissime registrazoni (il mio caso):

    codice:
    $langs = explode(',', $selected_languages); 
     
    foreach($langs as $lang) { 
        $res[] = " FIND_IN_SET('". mysql_escape_string($lang) . "', accounts.spoken_languages)"; 
    } 
     
    $query = 'SELECT  
        COUNT(accounts.user_id) as users_number,  
        countries.country_name  
        FROM accounts, countries  
        WHERE accounts.country_code=countries.country_code  
        AND (' . implode(' OR ', $res) . ') 
        GROUP BY countries.code;'; 
     
     //execute $query

  5. #5
    Utente di HTML.it
    Registrato dal
    Jan 2011
    Messaggi
    1,469
    non esiste un metodo semplice, e veloce.

    un modo veloce, ma non così semplice, è quello di simulare una ricerca full-text all'interno della stringa, appoggiandoti ad un motore esterno tipo sphinx.

    se usi mariadb, in realtà, è praticamente "interno" (lato php), altrimenti devi usare funzioni specifiche per la ricerca (niente di che, ma non è immediato).
    ---
    Puoi ottenere tempi dell'ordine di poche decine di millisecondi su tabelle con milioni di righe, SENZA tra l'altro caricare il server sql più di tanto (ritorna per default un massimo di 1000 righe, ma nel tuo caso immagino siano molte meno)

  6. #6
    @franzauker, ho scritto 'efficace', non 'semplice': non sarei qui se fosse semplice. Il mio database è mySql. Riguardo alla velocità, di cui dimostri di essere un esperto, cosa mi potresti dire in merito di una ricerca effettuata su una tabella supplementare di questo tipo:

    codice:
    users:
    user_id | user_name
             1 | 'eric'
             2 | 'gino'
             3 | 'laura' 
             4 | 'mario' 
             5 | 'luisa'
        ecc...| ecc...
    
    
    
    languages:
    language_id | language_code
             1 | 'it'
             2 | 'en-GB' 
             3 | 'fr' 
             4 | 'pt' 
             5 | 'el'
        ecc...| ecc...
    
    users_languages:
    user_id | language_id
             1 | 2
             1 | 3
             2 | 3 
             2 | 4 
             2 | 1
        ecc...| ecc...
    Infine, per selezionare tutte le persone che parlano una o più delle lingue selezionate:

    codice:
    SELECT users.* 
    FROM users, users_languages 
    WHERE users.user_id = users_languages.user_id
    AND users_languages.language_id IN ( '1,12,4')
    ?

    Ti ringrazio

  7. #7
    Utente di HTML.it
    Registrato dal
    Jan 2011
    Messaggi
    1,469
    che va bene, se metti un indice su entrambi i campi usati nel join.

    Ne vuoi uno ancora migliore? codifica come potenze di 2 i campi, e usa una maschera per trovarli direttamente, sia in AND tra di loro che in OR.

    Esempino

    1 = 'it'
    2 = 'en-GB'
    4 = 'fr'
    8 = 'pt'
    16 = 'el'

    12 = fr+pt

  8. #8
    Questa è geniale, ma devo studiare un po' la cosa per adattarla al mio proposito
    Grazie, ti faccio sapere.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.