Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Ricerca in Database

158 views
Skip to first unread message

Giovanni Gardelli

unread,
Sep 23, 2023, 8:44:47 AM9/23/23
to
Buongiorno a tutti,
Premetto di non essere esperto in database.
Dovrei effettuare in un database Firebird, una ricerca in una determinata colonna, che contiene una o più date parole Es.
SELECT*FROM Nome_tabella WHERE nome_campo LIKE Parola da cercare.
Ho provato con LIKE e CONTAINING ma mi restituisce anche parole che contengono la parola cercata Es. se la parola cercata è "case" Mi restituisce "case,caserma,casella ecc", mentre io devo ottenere la parola esatta.
Ho usato anche Wildcards (% o [ ]) ma senza risultato. sarò sicuramente io che sbaglio la sintassi della query, sarei grato se qualcuno mi facesse un esempio.
Grazie in anticipo a chi mi vorrà rispondere.
Uso delphi 10.2 e accedo a Firebird con dbExpress.

paolocarfi

unread,
Sep 25, 2023, 1:20:24 AM9/25/23
to
Prova con =
SELECT*FROM Nome_tabella WHERE nome_campo = Parola da cercare.

Alberto Salvati

unread,
Sep 25, 2023, 1:24:08 AM9/25/23
to
> Ho provato con LIKE e CONTAINING ma mi restituisce anche parole che contengono la parola cercata Es. se la parola cercata è "case"
> Mi restituisce "case,caserma,casella ecc", mentre io devo ottenere la parola > esatta.

Ciao.
Usare un DB senza troppa cognizione di causa è MALE.
Quindi, per prima cosa, non puoi prescindere dal leggere qualcosa sulla progettazione di un database relazionale ...

Infatti, Il tuo DB è SBAGLIATO E PROGETTATO MALE e DEVE ESSERE NORMALIZZATO. Ovvero, dovresti spezzare la tua tabella in 2

1) Tabella master con tutti i campi TRANNE quello che contiene le parole multiple, per comodità lo definisco "multiword".

2) Tabella detail con n record, dove N è il numero di parole contenute nel campo "multiword"
Questa tabella ha un suo ID come chiave primaria, un IDMASTER che punta all'omonimo campo della tabella al punto 1 e un campo "singleword".
Su questa tabella metti un indice UNIQUE basato su masterid + singleword, in modo da evitare che per lo stesso record MASTER in detail ci sia più di un record con la stessa parola.

A quel punto, la tua query diventa:

SELECT DISTINCT MASTER.MASTERID, MASTER.QUALCOSA, MASTER.QUALCOSALTRO. DETAIL.SINGLEWORD
JOIN DETAIL ON MASTER.MASTERID = DETAIL.MASTERID
WHERE DETAIL.SINGLEWORD = 'ES'

...lo so, lo so...mo starai pensando "...ma che rottura di balle!!!".
Hai ragione, ma, per la mia esperienza, un db progettato MALE, scoppia.
Non è un SE, ma un QUANDO.
E poi, quando succede, ristrutturare un db pieno di dati si fa, ma oltre ad essere scomodo è PERICOLOSO.
Quindi, meglio iniziare BENE, in quanto:

a) se inizi con la merda finisci con la merda
b) la merda, piu' la rimescoli e piu' puzza.


A.


paolocarfi

unread,
Sep 25, 2023, 2:21:15 AM9/25/23
to
Scusa, sono curioso, ma come hai fatto a capire che il db è progettato male e non è normalizzato?
???????????????????????????
Rivediamo i fatti dati.
Ha una tabella con un campo che contiene valori diversi, e fin qua questa è la norma (niente da normalizzare ne da riprogettare).
Deve fare una query su questa tabella e usa like o containing è giustamente il ritorno sara "case" "caseificio" ecc.
usando = il ritorno sarebbe solamente 'case', e tu cosa fai?
lo incasini con una join (che tra l'altro dovrebbe essere "inner") solo perche hai capito (credo che solo tu hai compreso questo con i dati disponibili)
che il suo database e una merda?
Complienti, bell'aiuto.

Alberto Salvati

unread,
Sep 25, 2023, 2:24:00 AM9/25/23
to

> Ha una tabella con un campo che contiene valori diversi,

Ecco.

A.

paolocarfi

unread,
Sep 25, 2023, 2:24:51 AM9/25/23
to
Ma ecco cosa? Hai scritto una minchiata fattene una ragione.

Alberto Salvati

unread,
Sep 25, 2023, 2:31:28 AM9/25/23
to

> Ma ecco cosa?

Se secondo te un campo con più valori non è cattiva progettazione, contento tu.

> Hai scritto una minchiata

Infatti la su query funziona.

A.

paolocarfi

unread,
Sep 25, 2023, 2:44:31 AM9/25/23
to
Su una tabella clienti la ragione sociale la metti la dove hai il codice ( e questo campo ha valori diversi) senza creare altre tabelle.
Facendo come tu dici, nel caso dato, sarebbe di certo una cattiva progettazione.
Dovevi solo rispondere al quesito posto, non fare il saputello e l'esegeta, visto che altro non si conosce.

Alberto Salvati

unread,
Sep 25, 2023, 3:01:24 AM9/25/23
to

> Su una tabella clienti la ragione sociale la metti la dove hai il codice ( e questo campo ha valori diversi) senza creare altre tabelle.
> Facendo come tu dici, nel caso dato, sarebbe di certo una cattiva progettazione.

Non + un "sarebbe": E' CATTIVA PROGETTAZIONE.
Probabilmente nella tua immane competenza non hai mai visto un database relazionale almeno in terza forma normale.
A proposito, tu conosci le forme normali? Nota che non parlo di fisico femminile, eh?

> Dovevi solo rispondere al quesito posto,

..dovevi.... Chi sei, TU, per dirmi quello che devo o non devo fare...?

Ah, poi un altra cosa. Questa è la tua risposta al quesito:

SELECT*FROM Nome_tabella WHERE nome_campo = Parola da cercare.

risposta che ovviamente NON FUNZIONA, indovina un po perche'...

A.

Giovanni Gardelli

unread,
Sep 25, 2023, 3:34:48 AM9/25/23
to
Grazie per la risposta, ma forse mi sono spiegato male, non devo trovare il campo = alla parola, ma bensì trovare i campi che contengono una o più parole date.

Giovanni Gardelli

unread,
Sep 25, 2023, 3:39:43 AM9/25/23
to
Il giorno lunedì 25 settembre 2023 alle 07:20:24 UTC+2 paolocarfi ha scritto:
Non credevo di scatenare una così accesa controversia, ho fatto una semplice domanda, sicuramente da persona meno esperta di chi mi ha risposto. Comunque non posso riprogrammare il database che deve restare così come è, e su questo dovrei fare una ricerca dei campi che contengono una o più parole date. Certamente ci sarà qualcuno così esperto da risolvere il problema, indicando una query appropriata, ringrazio comunque chi saprà e vorrà indicarmi una soluzione.

paolocarfi

unread,
Sep 25, 2023, 4:09:24 AM9/25/23
to
puoi utilizzare la clausola IN
where campo in [valore1, valore2 ecc.]
es: (['case','edifici','garage',ecc.])
Oppure farti una stored procedure dove all'interno puoi utilizzare varie query secondo le tue esigenze.

Giovanni Gardelli

unread,
Sep 25, 2023, 4:32:33 AM9/25/23
to
Grazie per la risposta, proverò a mettere in atto i suggerimenti.

Alberto Salvati

unread,
Sep 25, 2023, 4:43:24 AM9/25/23
to
> Non credevo di scatenare una così accesa controversia,

Tranquillo: non c'è nessuna controversia.

> ho fatto una semplice domanda, sicuramente da persona meno esperta di chi mi ha risposto.

La prima volta che si affronta qualcosa di nuovo siamo tutti inesperti...io, ad esempio, non so NULLA di html5 e javascript, PER ORA...
L'unico modo per arrivare ad una "seconda volta" è passare dalla prima.

Tornando al tuo problema,
Se i valori sono delimitati, tipo pipe , prenzi ovviamente con le pinze, si potrebbe provare una cosa del tipo:


select * from tabella where
campo STARTING WITH 'SE|'
or
CAMPO LIKE ('%|SE|%')
or
Position('|SE', campo) = CHAR_LENGTH(campo-3)

la prima condizione becca quelli che iniziano con SE e dopo hanno altri valori.
la seconda condizione becca quelli che contegono SE in mezzo ad altri valori
la terza condizione è tosta.... dovrebbe beccare quelli che hanno come ultimo valore SE ma quel "3" (ovvero length(SE) + 1 per il delimitatore,,) ovviamente andrebbe parametrizzato e non so se funziona...


Un altra via : Firebird ha l'operatore SIMILAR TO che permette l'uso di regular expression:

https://www.firebirdsql.org/file/documentation/html/en/refdocs/fblangref25/firebird-25-language-reference.html#fblangref25-commons-predsiimilarto

ma qua non ti so aiutare in quanto non le conosco... puoi vedere qualcosa qua:

https://regexr.com/

Se poi non sei vincolato a fare tutto via SQL, fai una query con like e poi ti devi inventare qualche post elaborazione.

1) avrai un TClientDataset avente gli stessi campi della tua tabella

2) fai la query select * from tabella where campo like '%SE%' usando una TSQLQuery

3) chiudi e resetti il TClientDataset

4) cicli sui record restituiti; per ogni record controlli se il campo con piu valori contiene esattamente "SE"

4a) se il record contiene esattamente "SE", vai in append di un record sul TClientDataset e popoli tutti i campi, poi fai una post.

4b) se il record *non* contiene esattamente "SE", lo scarti e e non fai nulla

4) sul tuo form o quello che è, mostrerai i dati presi NON dalla TSQLQuery ma da TClientDataset

Concordi con me che avere una seconda tabella come dicevo in una precedente risposta avrebbe reso tutto più sempice...?

A.

Giovanni Gardelli

unread,
Sep 25, 2023, 4:53:47 AM9/25/23
to
Ti ringrazio per la risposta dettagliata, credo di avere abbastanza per "impazzire", vedrò di studiare per quel che posso, e arrivare alla soluzione del problema. sicuramente con una seconda tabella sarebbe stato più semplice, però non mi è possibile. per quanto riguarda le regular expression sono proprio a zero, ma vedrò cosa riesco a fare.

Alberto Salvati

unread,
Sep 25, 2023, 6:00:18 AM9/25/23
to
> Ti ringrazio per la risposta dettagliata, credo di avere abbastanza per "impazzire", vedrò di studiare per quel che posso, e arrivare alla soluzione del problema.

Te lo auguro!


> sicuramente con una seconda tabella sarebbe stato più semplice, però non mi è possibile.

Quelle precisazioni non erano tanto per il caso corrente quanto in prospettiva futura.
Faccio questo lavoro da circa 30 anni e nel 95% dei casi ho visto db relazionali non progettati MALE...semplicemente non progettati.
Fermo restando le forme normali, ci sono alcuni indicatori da tener presente come questi ( ovviamente, ma non per tutti, la lista non è esaustiva...):

1) riesco a beccare in modo UNIVOCO e COMODO un qualsiasi record di una qualsiasi tabella?
2) ho valori ridondanti non necessari?
3) riesco a estrarre e/o aggregare dati per le esigenze che ho OGGI senza dover impazzire?
4) la struttura è abbastanza flessibile da permettermi, in futuro, di estrarre e/o aggregare dati per buona parte delle esigenze che potenzialmente potrebbero saltar fuori senza dover impazzire?
5) ho chiavi, se pur fittizie, non modificabili dall'utente, che posso usare nelle join in modo comodo?
6) ho il constraint NOT NULL su tutti i campi? Se no, come mai alcuni campi non hanno il NOT NULL? Se non sai rispondere a questa 2a domanda c'è casino...
7) ho abbastanza dati per contestualizzare un determinata operazione sul db per poter rispondere a domande del tipo "mi aspettavo A ma mi trovo B...?"
8) Tabelle o campi usano come NOMI parole chiave? Se si, quei nomi devono essere subito sostituiti, altrimenti sai che casino!
9) questa è una MIA paturnia: evitare gli underscore nei nomi...

> per quanto riguarda le regular expression sono proprio a zero, ma vedrò cosa riesco a fare.

Ti capisco. Sono molto potenti ma poco leggibili se non le hai studiate bene... :-|


A.

Daniele

unread,
Sep 25, 2023, 9:05:26 AM9/25/23
to
Ciao Alberto,
scusami ... mi sono perso nella discussione ...

Forse ho capito male .... ma Giovanni chiedeva com'era possibile fare una ricerca su una tabella dove "qualunque" campo del record contiene una data chiave di ricerca.

Un qualcosa come

Select * from mytable where TUTTI_I_CAMPI like '%qualcosa%'

Come si fa a dire "TUTTI_I_CAMPI" ?

Scusate se ho capto male ...

Ciao
Daniele

Giovanni Gardelli

unread,
Sep 25, 2023, 9:13:50 AM9/25/23
to
Ciao Daniele, ti rispondo per evitare malintesi, Se leggi la mia richiesta, si riferisce a una "data colonna" non a tutte le colonne.

Alberto Salvati

unread,
Sep 25, 2023, 9:30:29 AM9/25/23
to

> Come si fa a dire "TUTTI_I_CAMPI" ?
Da un punto di vista teorico questa cosa non ha molto senso.
Ha senso su un limitato numero di campi, ad esempio, data una tabella con codice e descrizione, l'utente digita un valore chiave e ti fai una cosa di questo tipo:

select * from tabella
where
codice like :p1
or
codice like :p2

dove p1 e p2 sono 2 parametri i cui valori assegni a runtime.

Teoria a parte, per una query che cerca su tutti i campi, su un relazionale ti tocca:

1) indicare n condizioni where specifice, dove n è il numero di campi della tabella, magari filtrato per tipo di dato...
Se l'utente cerca "pippo" una where su campi numerici non la puoi fare; per contro se l'utente cerca "123" una where su campi numerici potrebbe avere senso.

2) aggiungere una sola condizione where del tipo:
select * from tabella
where
campo1 || campo2 || campo3 || ...campo n like :p1

Ma in entrambi i casi non puoi generalizzarla: DEVI specificare tutti i campim uno per uno, nome per nome.

Se invece usi un db NoSQL tipo MongoDb, credo (e sottlineo credo...) si possa definire una condizione che tenga conto di tutti i campi in modo implicito.
Ma ripeto, è solo un mio pensiero non supportato dai fatti: non conosco (ancora!) MongoDb o più in generale, database NoSQL.

A.

Daniele

unread,
Sep 25, 2023, 11:26:42 AM9/25/23
to
Ciao Giovanni,
Ho capito male leggendo questa tua risposta:

> > Grazie per la risposta, ma forse mi sono spiegato male, non devo trovare il campo = alla parola, ma bensì trovare i campi che contengono una o più parole date.

Niente di che ... tutto risolto al meglio ...

Ciao
Daniele


Alessandro B.

unread,
Sep 26, 2023, 6:36:20 AM9/26/23
to
Credo si possano fare almeno due distinzioni:

a) al momento della progettazione del database era già evidente che si sarebbero dovute eseguire ricerche su almeno un campo per singole parole chiave
b) al momento della progettazione del database questa ricerca non era stata evidenziata come necessaria

Se siamo nella situazione a) probabilmente il database non è stato strutturato nel modo migliore per l'estrazione del dato richiesto
In questo caso darei ragione ad Alberto.

Se siamo nella situazione b) la domanda fatta può essere lecita: chiede se qualcuno ha una idea per estrarre l'informazione anche se il database non era stato predisposto per questa gestione. Non so voi, ma a me è capitato più volte di avere specifiche che sono cambiate nel tempo.
Al momento non credo sia gestibile solo con comandi sql diretti anche se non conosco nel modo specifico Interbase
Credo sia necessario processare a posteriori i record estratti con delle elaborazioni procedurali

Volendo aggiungere che sarebbe anche necessario gestire le combinazioni tipo "case", "casa", "caso" ... ma qui si apre un altro fronte di ragionamento.

Alessandro

Alberto Salvati

unread,
Sep 26, 2023, 8:23:13 AM9/26/23
to

Se DOPO, salta fuori il caso non previsto e ti tocca "tapparti il naso" e mettere una pezza del genere, ok.
Ma se poi, sulla pezza devi farci delle query, la pezza è peggiore del buco: DEVI, E SOTTOLINEO, DEVI, FARE RE FACTORING.
Alla fine vale il concetto zen "la via breve è la via lunga"... :-|


A.

Alessandro B.

unread,
Sep 26, 2023, 10:25:05 AM9/26/23
to
Concordo al 1000%

Enrico Bianchi

unread,
Nov 13, 2023, 12:25:41 PM11/13/23
to
On 2023-09-25, Giovanni Gardelli <1gio...@gmail.com> wrote:

> Comunque non posso riprogrammare il database che deve restare così come è,

Come mai?

Enrico

Alberto Salvati

unread,
Nov 14, 2023, 10:53:31 AM11/14/23
to
> Come mai?

Perchè pur di risparmiare non si bada a spese.

A.
0 new messages