Newsgroup: it.comp.software.database
Titolo: MYSQL -> ricerca valore

Salve,
ho una tabella con un campo varchar che contiene valori tipo ...
1,2,3,4
1,2
0,2
10,20,30
31, 40,50
5,3,9
100,200,1,12
ecc.ecc.
come faccio, per esempio, a pescare solo i campi che contengono
per esempio il valore 3 ?
mi veniva da pensare con un LIKE %3% ... ma cosě facendo mi
pesca anche il 30 .... il 31 .... ecc.ecc.
come posso quindi prelevare solo quelli che contengono IL 3 PURO ?
ciao e grazie 1000 !

 pesca anche il 30 .... il 31 .... ecc.ecc.
oops, forse mi rispondo da sola ...
non ditemi che bastava un LIKE %,3,% .... eheheh ;-)

 ha scritto nel messaggio
news:c4jj25$u8v$1...@news.ngi.it...

ci stavo pensando anche io... il problema č che se hai un field col valore:
3,10,100
non te lo trova perchč non inizia con la virgola... idem se il 3 č in
fondo...
mmm, rimango in ascolto pure io ;)
Matteo

 Matteo
YEAH Matteo !
ma abbiamo la TELEPATIA !??!?!
ti giuro che appena l'hai scritto, stavo scrivendo e pensando la stessa
identica cosa ...
in effetti sono al punto di partenza .... :-(
sto provando con le REGEXP ... ma non ci sono ancora riuscita ...
c'è qualche anima pia che sappia farlo ?!? sono alla disperazione, sono ore
ed ore
che ci sbatto la testa ! :-(
devo estrarre quei maledetti numeri ...
sia che siano in prima posizione ( quindi niente virgola prima )
sia che siano all'ultima ( quindi niente virgola dopo )
sia che siano in mezzo ( virgola prima e dopo ) ...
ed ovviamente, che mi peschi i valori PURI E VERI, e non "13" al posto di un
semplice 3, e così via ....
insomma ... se il campo è 1,2,3,4,5,6,7,8,9,10,11,12 ...
ed io voglio estrarre il numero 1 , come faccio ? non voglio anche il 10, l'
11 ed il 12 !!!
e visto che si trova in prima posizione, un like %,1,% non va bene !
:-(((((((((((((((
esiste una formula REGEXP che vada bene per qualsiasi posizione abbia il
valore da prelevare ?
e che soprattutto peschi i numeri VERI e non anche quelli "composti" da
quella cifra ?!?!
____________________
GRAZIE super 1000 !

 che ci sbatto la testa ! :-(
Non è molto bello, ma è l'unica cosa che mi viene in mente al momento:
select ... where concat(',', campo, ',') like '%,3,%'
--
Jax
====
Il buon nome vale più di grandi ricchezze; la stima, più che l'oro e
l'argento. (Salomone)

 select ... where concat(',', campo, ',') like '%,3,%'
lo provo subito grazie !
ma ha conseguenze sulle prestazioni, con molte query,
di un altro ipotetico metodo più "bello" ?
altrimenti, mi basta che funzioni,
sempre che non vada a discapito
delle prestazioni appunto.
p.s
cosa fa in realtà quel CONCAT ? ho cercato
sul sito mysql, ma non ho ben capito perché
concatenare in quel modo mi potrebbe risolvere il problema ...
sorry for the ignorance ;-)

 delle prestazioni appunto.
le prestazioni le dovrebbe degradare sicuramente, probabilmente perchè sarà
costretto a fare un full scan della tabella senza usare l'indice...
In pratica la richiesta è di prendere il campo, metterci una virgola davanti
e una dietro e se c'è quello che cerchi con prima e dopo una virgola di
mostrare il record.
situazione:
"1,3,13" cerchi il "3"
lui mette una virgola prima e dopo al field e anche a quello che cerchi
",1,3,13," e ",3,"
facendo una ricerca dentro il testo, ",3," lo troverebbe sia all'inizio, sia
alla fine, ma il 3 non composito dentro un altro numero (es 13)
Ciao
Matteo

 alla fine, ma il 3 non composito dentro un altro numero (es 13)
grazie ad entrambi ... sia per il suggerimento che
per la spiegazione gentilissima ...
ma ora mi preoccupo appunto per le prestazioni ...
perché è un grosso DB e quella query verrà sparata moltissime volte ...
ma non c'è modo di farla con le REGEXP ?!?
che so .. qualcosa del tipo ...  [^,\d]?3[^,\d]? ..... [^\d],?3,?[^\d] ....
blah blah blah
ne ho provate a decine .....
 .... non dovrei esserci troppo lontana ... in alcuni casi
ottengo l'estrazione del 3 ( in tutte le sue posizioni ) ....
ma purtroppo anche i 13, 300, 113, ecc.ecc.
resto in attesa fiduciosa ... :-)
non c'è nessun guru delle regexp in giro ? ;-)

 per esempio il valore 3 ?
Prova:
======================
select
 *
from
 tab
where
 col like '3,%'
or
 col like '%,3,%'
or
 col like '%,3'
======================
Ovviamente le prestazioni saranno scarse, ma ti succederà in qualsiasi caso
tu cerchi di
recuperare questi dati organizzati in questo modo
Ciao
-- 
Fabrizio Maccarrone
--
YAMSSQLU
(Yet Another MSSQL User)

 non c'è nessun guru delle regexp in giro ? ;-)
Chi mi ha chiamato? :-)
Proprio alla fine del capitolo "G MySQL Regular Expressions"
trovi queste righe che, se ne ho ben capito il significato,
sembrano scritte per il tuo caso:
[[:<:]]
[[:>:]]
     These match the null string at the beginning and end of a word
respectively. A word is defined as a sequence of word characters which
is neither preceded nor followed by word characters. A word character is
an alnum character (as defined by ctype(3)) or an underscore (_).
mysql> SELECT "a word a" REGEXP "[[:<:]]word[[:>:]]";      -> 1
mysql> SELECT "a xword a" REGEXP "[[:<:]]word[[:>:]]";     -> 0
Provando:
select "1,2,3" regexp "[[:<:]]1[[:>:]]" ;     --> 1
select "1,2,3" regexp "[[:<:]]2[[:>:]]" ;     --> 1
select "1,2,3" regexp "[[:<:]]3[[:>:]]" ;     --> 1
select "33,33,33" regexp "[[:<:]]3[[:>:]]" ;  --> 0
Bye
gp
-- 
gpb chiocciolina
freemail point it

 non c'è nessun guru delle regexp in giro ? ;-)
Seconda soluzione (tralaltro più semplice):
il numero (o stringa) che cerchi alla sua sinistra
avrà una virgola oppure l'inizio riga, a destra
una virgola oppure il fine riga, quindi:
select "11,11,11" regexp "(^|,)1($|,)"  --> 0
select "1,2,3" regexp "(^|,)1($|,)" ;   --> 1
select "1,2,3" regexp "(^|,)2($|,)" ;   --> 1
select "1,2,3" regexp "(^|,)3($|,)" ;   --> 1


VI RINGRAZIO INFINITAMENTE TUTTI !
mi avete salvata dalla disperazione tecnica ;-)
ero sull'orlo di una crisi di nervi, eheheh
comunque, alla fine, dopo vari test di performances,
ho scelto la soluzione "(^|,)1($|,)" di Paolo ( sei un grande ! ).
siete stati molti gentili, devo riconoscere che
questo è davvero un grande newsgroup !
CIAO, un super bacione !

per esempio il valore 3 ?
Be', il sistema piu' pratico sarebbe forse di aggirare il problema del
tutto. Questo, ammesso che tu possa variare la struttura del database,
altrimenti quanto segue non ti serve a niente :-(
Ed ammesso che il costo di implementare questa soluzione non superi il
bisogno che ne hai, e/o pensi di avere in futuro, altrimenti e' chiaro
che non ti conviene.
Ti servono altre due tabelle, una con i valori che cerchi (1,2,3,...),
e una di congiunzione. Nel tuo caso VALUETYPE e' integer, e, di solito
almeno, TABLEIDTYPE e' anche lui integer (la pkey della tabella dentro
cui cerchi adesso).
CREATE TABLE srcValues ( idVal integer not null primary key
auto_increment, value VALUETYPE );
CREATE INDEX srcValue_ndx ON srcValues( value [, idVal]);
CREATE TABLE srcJoin ( idTable TABLEIDTYPE, idVal integer );
A questo punto, invece di
SELECT ... FROM myTable WHERE campo LIKE...
scrivi
SELECT ... FROM myTable JOIN srcJoin ON ( myPKey = idTable )
	JOIN srcValues USING ( idVal ) WHERE value=3;
	...oppure (2)
		WHERE value > 3 AND value < 17
	...oppure (3)
		WHERE ( value % 13 ) = 9
Dal punto di vista prestazionale, il margine e' piccolo - se cerchi su
un valore singolo - ma puo' diventare enorme, se la condizione che usi
per la ricerca e' complessa tipo la (3), o se cerchi su valori di tipo
non intero a colpi di regexp, o se myTable ha molti record.
Inoltre hai tutti i tuoi valori ordinati in una tabella singola - cosa
che puo' venire utile in fase di sviluppo dell'interfaccia - e ti puoi
anche fare una query per sapere quali valori un record "POTREBBE avere
associati" (perche' esistono in srcValues) ma non ha.
Leonardo alla rinfusa
-- 
Nach doiligh domhsa mo chailin a mholadh
'S ni he amhain mar bhi si or
Bhi si mar gath greine a dhul in eadan na gloinne
Is bhi sceimh mhna na finne le mo cailin or

 associati" (perche' esistono in srcValues) ma non ha.
sei stato gentilissimo ed esaustivo !
rifletterò su quanto mi hai consigliato ...
ed essendo in effetti il sistema in fase di sviluppo iniziale e quindi anche
concettuale,
pertanto, apportare una modifica alla logica dei dati, non sarebbe ancora
troppo
dispendioso in termini di tempo / risorse.
soprattutto perché mi hai giustamente suggerito che in questo modo, potrei
eseguire una
query per sapere quali valori un record "POTREBBE avere associati" ...
e riflettendoci bene, potrebbe risultare molto utile in uno stadio avanzato
e futuro
di questo sistema d'interfacciamento al DB ...
presumo che mi hai risparmiato ore ed ore di "patch & fixes" future ...
per rattoppare questa eventuale feature che quasi sicuramente mi sarà
richiesta.
Ti Ringrazio Infinitamente,
Un Bacio.


Lasciando le cose come stanno, la soluzione del REGEXP 
"[[:<:]]parola[[:>:]]" e' quella piu' precisa, ma non quella piu' 
efficiente.
Se i valori nel tuo campo non sono piu' di 64, puoi modificare la 
struttura della tabella e usare il tipo SET:
http://www.mysql.com/doc/en/SET.html
CREATE TABLE prova (
   i int(11) NOT NULL default '0',
   valore set('0','1','2','3','5','6','9','10','30','120') default NULL,
   PRIMARY KEY  (i)
) TYPE=MyISAM;
INSERT INTO prova VALUES (1,'1,9,30');
INSERT INTO prova VALUES (2,'3,5,120');
INSERT INTO prova VALUES (3,'1,3,30');
INSERT INTO prova VALUES (4,'5');
INSERT INTO prova VALUES (5,'1,3,30');
INSERT INTO prova VALUES (6,'6,9,30');
mysql> select * from prova;
+---+---------+
| i | valore  |
+---+---------+
| 1 | 1,9,30  |
| 2 | 3,5,120 |
| 3 | 1,3,30  |
| 4 | 5       |
| 5 | 1,3,30  |
| 6 | 6,9,30  |
+---+---------+
6 rows in set (0.00 sec)
mysql> select * from prova where find_in_set('3',valore);
+---+---------+
| i | valore  |
+---+---------+
| 2 | 3,5,120 |
| 3 | 1,3,30  |
| 5 | 1,3,30  |
+---+---------+
3 rows in set (0.00 sec)
Ciao
gmax
-- 
   ____ ____  _____ _   _
  / _  |    \(____ ( \ / )
( (_| | | | / ___ |) X (
  \___ |_|_|_\_____(_/ \_)
(_____|
Sapere, saper fare, fare, far sapere
http://gmax.oltrelinux.com
Speaker at the 2nd MySQL Users Conference, Orlando, FL, 2004
http://www.mysql.com/events/uc2004/schedule-wednesday.html

 | 3 | 1,3,30  |
ciao, prima di tutto grazie per l'interessamento.
scusa, probabilmente mi sbaglio, ma quando hai fatto
un where find_in_set('3',valore) , ti ha restituito le 3 righe
che contengono il valore "3" all'interno del set di valori, no ?
beh ... mi sembra appunto che cosě facendo, ti ritorna
anche il 30 per esempio ... cercando solo il '3' ...
scusa l'ignoranza, ma per me č un tipo di dati nuovo e
non ci sto capendo moltissimo sulla logica di questi SET ...
grazie per l'eventuale ulteriore illuminazione, ciao !

 


 ecc.ecc.




-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it