← Portale
Guida operativa · 3ª AFM / RIM

Le Query in
LibreOffice Base

Guida pratica all'interfaccia grafica — niente SQL, solo click. Database di esempio: negozio multisettore NERD-HERD.

🗄️ NERD-HERD.odb
HSQLDB incorporato
⬇ Scarica il DB
Sezioni →
00

Cos'è una query?

Una query (dall'inglese: interrogazione) è una domanda che facciamo al database. Il database risponde mostrando una tabella con i dati che soddisfano i nostri criteri.

// Una query può:

  • Scegliere quali campi mostrare (es. solo nome e prezzo, non tutto)
  • Scegliere quali righe mostrare (es. solo i prodotti sotto i 10€)
  • Combinare dati da più tabelle collegate
  • Ordinare i risultati (es. dal più economico al più caro)
  • Raggruppare e calcolare medie, somme, conteggi

Il database NERD-HERD

Gli esempi di questa guida usano il database di un negozio multisettore. Ecco la struttura delle tabelle principali che useremo:

NERD-HERD.odb : NERD-HERD — LibreOffice Base: Struttura relazioni
▦ FORNITORE 🔑 PIVA Ragione_Sociale Contatto_Email 1 n ▦ CATALOGO_FORNITORE 🔑 FK_EAN 🔑 FK_PIVA Prezzo_Acquisto n 1 ▦ PRODOTTO 🔑 EAN Descrizione Prezzo_Listino FK_COD_Tipo n 1 ▦ TIPOLOGIA 🔑 COD_Tipo Descrizione

🔑 = chiave primaria  ·  n—1 = relazione molti-a-uno

01

Aprire il Query Designer

Nel pannello sinistro di LibreOffice Base, clicca su Ricerche.
Nel pannello delle attività (in alto a destra), fai doppio clic su «Crea ricerca in vista struttura…»
Si aprirà la finestra Aggiungi tabella o ricerca: seleziona le tabelle che ti servono e clicca Aggiungi per ciascuna, poi Chiudi.
⚠️
Attenzione: solo tabelle collegate! Aggiungi solo le tabelle che sono collegate tra loro (con una relazione). Se aggiungi tabelle non collegate, il database combina tutte le righe tra loro (prodotto cartesiano) e i risultati saranno sbagliati e moltissimi.
Pagina Ricerche di LibreOffice Base
Schermata reale — Sezione «Ricerche» con le tre opzioni disponibili
Dialog Aggiungi tabella o ricerca
Schermata reale — Finestra «Aggiungi tabella o ricerca»
💡
Suggerimento: Puoi aggiungere più tabelle in sequenza senza chiudere il dialog: seleziona una tabella → Aggiungi → seleziona un'altra → Aggiungi → poi Chiudi.
02

L'interfaccia del Query Designer

Il Query Designer è diviso in tre zone. Impariamo a riconoscerle prima di procedere.

NERD-HERD.odb : Ricerca1 — LibreOffice Base: Struttura ricerca
FileModificaVisualizzaInserisciStrumentiFinestraAiuto
💾
▦ Esegui
AZ↓
AZ↑
𝑓x
Tutto ▾
ZONA A — Tabelle
FORNITORE
PIVA
Ragione_Sociale
Contatto_Email
———
CATALOGO_FORNITORE
FK_EAN
FK_PIVA
Prezzo_Acquisto
ZONA B — Griglia criteri
col. 1col. 2col. 3col. 4col. 5
Campo
Alias
Tabella
Ordine
Visibile
Funzione
Criterio
o
o
Query Designer con tabelle caricate
Schermata reale — Il Designer con 4 tabelle collegate e la griglia vuota pronta

Le righe della griglia — a cosa servono

RigaCosa inserireEsempio
CampoIl nome del campo da includere nella queryRagione_Sociale
AliasUn nome alternativo per l'intestazione colonna nel risultatoFornitore
TabellaLa tabella di provenienza (compilato automaticamente)FORNITORE
OrdineOrdinamento: crescente o decrescentecrescente
Visibile✓ = il campo appare nel risultato; ☐ = usato solo per filtrispunta ✓ / ☐
FunzioneFunzione di aggregazione (Somma, Media, Conteggio…)AVG
CriterioCondizione di filtro (riga principale — AND implicito tra colonne)> 10
oCondizione alternativa — OR con la riga Criterio'CASA'

Come aggiungere un campo alla griglia

Doppio clic sul nome del campo nella casella tabella (Zona A). Il campo si aggiunge automaticamente alla prima colonna libera.
Oppure: trascina il campo dalla casella tabella fino alla riga "Campo" nella griglia.
Oppure: clicca sulla cella vuota della riga "Campo" e scegli dal menu a tendina.
03

La prima query — selezione semplice

Obiettivo: Creare un catalogo fornitori con Ragione_Sociale, Descrizione (tipologia), Descrizione (prodotto) e Prezzo_Acquisto.

Aggiungi le tabelle: FORNITORECATALOGO_FORNITOREPRODOTTOTIPOLOGIA (sono tutte collegate tra loro).
Fai doppio clic su Ragione_Sociale in FORNITORE → entra nella colonna 1 della griglia.
Fai doppio clic su Descrizione in TIPOLOGIA → colonna 2.
Fai doppio clic su Descrizione in PRODOTTO → colonna 3.
Fai doppio clic su Prezzo_Acquisto in CATALOGO_FORNITORE → colonna 4.
Assicurati che tutte le caselle Visibile siano spuntate (✓).
Clicca sul pulsante Esegui la ricerca (▶ o F5) per vedere i risultati.
Salva la query con Ctrl+S e daile un nome significativo, es. Q_CatalogoFornitori.
Query di selezione completa con risultati
Schermata reale — Query completata: griglia compilata in basso, risultati visibili in alto (41 record)
ℹ️
La riga "Tabella" si compila da sola quando aggiungi un campo con doppio clic. Se hai due campi con lo stesso nome (es. due Descrizione), controlla la riga Tabella per capire da quale tabella proviene ciascuno.
04

Ordinamenti — singoli e multipli

Per ordinare i risultati, si usa la riga Ordine nella griglia. Puoi scegliere crescente (A→Z, 0→9) o decrescente (Z→A, 9→0).

Ordinamento singolo

Clicca sulla cella della riga Ordine sotto il campo che vuoi ordinare → apparirà un menu a tendina con le opzioni.

Struttura ricerca — Ordinamento singolo
Ragione_Sociale Descrizione Prezzo_Acquisto
CampoRagione_SocialeDescrizionePrezzo_Acquisto
Alias
TabellaFORNITOREPRODOTTOCATALOGO_FORNITORE
Ordinecrescente
Visibile
Criterio

Ordinamento multiplo

Puoi ordinare per più campi contemporaneamente: l'ordinamento è gerarchico — prima si ordina per il campo più a sinistra nella griglia, poi per quello successivo a parità del precedente.

💡
Trucco: Se vuoi ordinare per Tipologia prima e poi per Prodotto, metti la colonna Tipologia a sinistra rispetto alla colonna Prodotto nella griglia. L'ordine delle colonne conta!
Ordinamento multiplo crescente su tre campi
Schermata reale — Ordinamento crescente su tre campi: Ragione_Sociale, Descrizione (TIPOLOGIA) e Descrizione (PRODOTTO)
Struttura ricerca — Ordinamento multiplo
Ragione_Sociale Descrizione Descrizione Prezzo_Acquisto
CampoRagione_SocialeDescrizioneDescrizionePrezzo_Acquisto
TabellaFORNITORETIPOLOGIAPRODOTTOCATALOGO_FORNITORE
Ordine crescente crescente crescente
Visibile
Criterio

↑ Prima si raggruppano per fornitore, poi per tipologia, poi per prodotto — tutto in ordine alfabetico crescente.

05

Filtri statici

Un filtro statico è una condizione fissa scritta direttamente nella griglia. Il valore non cambia mai — ogni volta che esegui la query, il risultato è filtrato sempre allo stesso modo.

Il filtro va inserito nella riga Criterio della colonna del campo su cui vuoi filtrare.

Operatori disponibili

OperatoreSignificatoEsempio
= oppure nienteUguale a'Articoli Casalinghi' oppure Articoli Casalinghi
<>Diverso da<> 'CASA'
> <Maggiore / Minore> 10
>= <=Maggiore o uguale / Minore o uguale<= 5.00
COME (o LIKE)Contiene (usa % come jolly)COME 'Articoli%'
ℹ️
Testo vs numeri: I valori testuali vanno tra apici singoli: 'CASA'. I numeri si scrivono senza apici: 10. LibreOffice spesso aggiunge gli apici da solo per il testo.
Due filtri statici in OR
Schermata reale — Filtro statico > 10 su Prezzo_Acquisto (riga Criterio) e 'CASA' su COD_Tipo (riga «o»)

Esempio pratico

Query: prodotti con prezzo di acquisto maggiore di 10 euro.

Struttura ricerca — Filtro statico
Ragione_SocialeDescrizionePrezzo_Acquisto
CampoRagione_SocialeDescrizionePrezzo_Acquisto
TabellaFORNITOREPRODOTTOCATALOGO_FORNITORE
Ordinecrescente
Visibile
Criterio> 10
o

Il carattere jolly % (con COME)

L'operatore COME (in inglese LIKE) permette di cercare testi che assomigliano a un modello, usando % come carattere jolly — cioè "qualsiasi cosa, di qualsiasi lunghezza".

CriterioSignificatoTrova, ad esempio
COME 'Art%'Inizia per "Art"Articoli Casalinghi, Articoli da Regalo
COME '%Pulizia'Finisce per "Pulizia"Igiene e Pulizia
COME '%Casa%'Contiene "Casa" in qualsiasi posizioneArticoli Casalinghi
COME 'B_llitore'_ = esattamente un carattereBollitore
💡
% vs _ — Il % sostituisce zero o più caratteri qualsiasi. Il trattino basso _ sostituisce esattamente un carattere. Nella pratica userai quasi sempre %.
06

Filtri dinamici (con parametri)

Un filtro dinamico chiede all'utente di inserire il valore ogni volta che la query viene eseguita. È molto utile quando vuoi usare la stessa query per ricerche diverse.

Per creare un filtro dinamico, al posto del valore fisso scrivi ? oppure :NOME_PARAMETRO.

Usa ? quando hai un solo parametro per campo. All'esecuzione, appare un dialog che chiede il valore.

Struttura ricerca — Parametro ?
Ragione_SocialeDescrizione (TIPOLOGIA)Descrizione (PRODOTTO)Prezzo_Acquisto
CampoRagione_SocialeDescrizioneDescrizionePrezzo_Acquisto
TabellaFORNITORETIPOLOGIAPRODOTTOCATALOGO_FORNITORE
Ordinecrescentecrescentecrescente
Visibile
Criterio?> ?

Il dialog apparirà due volte: prima per la Descrizione, poi per il Prezzo.

Usa :NOME quando vuoi dare nomi chiari ai parametri, o usare lo stesso valore in più punti. I nomi appaiono nel dialog di inserimento.

Struttura ricerca — Parametri :NOME
Ragione_SocialeDescrizioneDescrizionePrezzo_Acquisto
CampoRagione_SocialeDescrizioneDescrizionePrezzo_Acquisto
TabellaFORNITORETIPOLOGIAPRODOTTOCATALOGO_FORNITORE
Ordinecrescentecrescentecrescente
Visibile
Criterio:TIPO_PRODOTTO> :PMIN E < :PMAX

Il dialog "Specifica parametro"

Quando esegui una query con parametri, LibreOffice mostra questo dialog per ogni parametro:

Dialog Specifica parametro
Schermata reale — Il dialog chiede il valore per ciascun parametro (qui: Descrizione e Prezzo_Acquisto)
Filtro con range PMIN PMAX
Schermata reale — Filtro con range: > :PMIN E < :PMAX su Prezzo_Acquisto
💡
Range di valori: Per filtrare tra un minimo e un massimo, scrivi: > :PMIN E < :PMAX nella stessa cella Criterio. La parola E (in italiano) unisce le due condizioni sulla stessa colonna.

COME con parametro dinamico — ricerca per parola chiave

Combinando COME con un parametro ottieni una ricerca flessibile: l'utente digita una parola e la query trova tutti i record che la contengono, senza sapere in anticipo cosa cercherà.

Griglia con COME dinamico
Schermata reale — COME '%' || :inserisci_parte_nome || '%' nella riga Criterio: il % prima e dopo garantisce che la parola venga trovata ovunque nella stringa
Dialog parametro con valore Carta
Schermata reale — L'utente inserisce Carta come valore del parametro
Risultato ricerca Carta
Schermata reale — Tutti i prodotti che contengono "Carta" nella descrizione
💡
Il simbolo || concatena testo. '%' || :inserisci_parte_nome || '%' costruisce il pattern %Carta% in modo dinamico — il valore inserito dall'utente viene "avvolto" dai due % automaticamente.
07

Filtri in AND e in OR

// La regola fondamentale:

  • AND → condizioni sulla stessa riga (riga Criterio, colonne diverse)
  • OR → condizioni su righe diverse (riga Criterio e righe «o»)

Scenario: voglio i prodotti di tipologia "Articoli Casalinghi" CON prezzo tra 5 e 25 euro. Entrambe le condizioni devono essere vere contemporaneamente → AND.

Struttura ricerca — AND
Ragione_SocialeDescrizione (TIPOLOGIA)Descrizione (PRODOTTO)Prezzo_Acquisto
CampoRagione_SocialeDescrizioneDescrizionePrezzo_Acquisto
TabellaFORNITORETIPOLOGIAPRODOTTOCATALOGO_FORNITORE
Ordinecrescentecrescentecrescente
Visibile
Criterio:TIPO_PRODOTTO> :PMIN E < :PMAX
o

Le condizioni sono sulla stessa riga Criterio → si leggono come AND: tipologia = X E prezzo tra min e max.

Filtri AND su campi diversi
Schermata reale — AND tra TIPO_PRODOTTO e range di prezzo (tre parametri)

Scenario: voglio i prodotti di tipologia "Articoli Casalinghi" OPPURE quelli con prezzo maggiore di 10. Basta che una delle condizioni sia vera → OR.

Struttura ricerca — OR
Ragione_SocialeCOD_TipoDescrizione (PRODOTTO)Prezzo_Acquisto
CampoRagione_SocialeCOD_TipoDescrizionePrezzo_Acquisto
TabellaFORNITORETIPOLOGIAPRODOTTOCATALOGO_FORNITORE
Ordinecrescentecrescente
Visibile
Criterio> 10
o'CASA'

Le condizioni sono su righe diverse → si leggono come OR: prezzo > 10 OPPURE COD_Tipo = 'CASA'.

Filtri statici in OR
Schermata reale — Filtro statico > 10 (riga Criterio) e 'CASA' (riga «o») — sono in OR tra loro

Scenario avanzato: voglio i prodotti della categoria 'CASA' con prezzo tra PMIN e PMAX, OPPURE i prodotti di qualsiasi altra categoria con prezzo tra PMIN e PMAX.

AND e OR combinati
Schermata reale — AND tra range prezzo e categoria (riga Criterio) con OR sulla categoria (riga «o»)
Risultato filtro OR con parametro CASA
Schermata reale — Risultato della query filtrata per categoria 'CASA' con prezzo nel range specificato
⚠️
Ricorda la regola visivamente: immagina ogni riga come una "domanda alternativa". Se una riga è soddisfatta, il record viene incluso. Dentro ogni riga, tutte le condizioni devono essere vere (AND).
08

Visibile e Non visibile

La casella Visibile controlla se un campo appare nelle colonne del risultato. Un campo può essere presente nella griglia (e usato per filtrare) senza essere mostrato nel risultato.

// Quando si usa "non visibile"?

  • Quando vuoi filtrare per un campo ma non vuoi mostrarlo nel risultato (es. filtri per COD_Tipo ma mostri solo la Descrizione)
  • Quando vuoi ordinare per un campo senza mostrarlo

Esempio: filtrare per COD_Tipo senza mostrarlo

Struttura ricerca — Campo non visibile
Ragione_SocialeCOD_Tipo ⚠Descrizione (TIPOLOGIA)Descrizione (PRODOTTO)Prezzo_Acquisto
CampoRagione_SocialeCOD_TipoDescrizioneDescrizionePrezzo_Acquisto
TabellaFORNITORETIPOLOGIATIPOLOGIAPRODOTTOCATALOGO_FORNITORE
Ordinecrescentecrescentecrescente
Visibile
Criterio> :PMIN E < :PMAX
o:CAT_PRODOTTO

⚠ COD_Tipo: la spunta Visibile è vuota → non apparirà nel risultato, ma il filtro funziona lo stesso.

Campo COD_Tipo non visibile con filtro attivo
Schermata reale — COD_Tipo ha Visibile ☐ ma il filtro :CAT_PRODOTTO è attivo nella riga «o»
Risultato senza COD_Tipo nelle colonne
Schermata reale — Il risultato non mostra COD_Tipo, ma i dati sono filtrati correttamente per categoria
💡
Differenza pratica: Con Visibile ✓ l'utente vede anche il codice "CASA". Con Visibile ☐ vede solo Fornitore, Descrizione categoria, Prodotto e Prezzo — più pulito e leggibile.
09

Funzioni di aggregazione

Le funzioni di aggregazione permettono di fare calcoli su gruppi di record: contare quanti prodotti ha ogni fornitore, calcolare il prezzo medio per categoria, trovare il massimo, ecc.

Per usarle, occorre attivare la riga Funzione nella griglia (di solito appare già; se non fosse visibile, vai su Visualizza → Funzioni).

Le funzioni disponibili

FunzioneSignificatoUsata su
GruppoRaggruppa i record con lo stesso valoreCampi testuali (nome, categoria…)
ConteggioConta quanti record ci sono nel gruppoQualsiasi campo
AVGCalcola la media dei valoriCampi numerici
SommaCalcola la somma dei valoriCampi numerici
MaxTrova il valore massimoCampi numerici o testo
MinTrova il valore minimoCampi numerici o testo
⚠️
Regola fondamentale: Ogni campo nella griglia deve avere una funzione. I campi "normali" (quelli da cui raggruppi) usano Gruppo. I campi calcolati usano Conteggio, AVG, Somma, ecc.

Esempio: quanti prodotti per fornitore e tipologia + prezzo medio

Obiettivo: per ogni fornitore e ogni tipologia, sapere quanti prodotti ci sono e qual è il prezzo medio di acquisto.

Q_CatalogoFornitori_Gruppo — Struttura ricerca
Ragione_Sociale Descrizione (TIPOLOGIA) Descrizione (PRODOTTO) Prezzo_Acquisto
CampoRagione_SocialeDescrizioneDescrizionePrezzo_Acquisto
AliasNUM PRODOTTIPR. MEDIO
TabellaFORNITORETIPOLOGIAPRODOTTOCATALOGO_FORNITORE
Ordinecrescentecrescente
Visibile
Funzione Gruppo Gruppo Conteggio AVG
Criterio
Query di raggruppamento con Conteggio e AVG
Schermata reale — Query con doppio raggruppamento, Conteggio (alias: NUM PRODOTTI) e AVG (alias: PR. MEDIO) — 17 righe di risultato

L'Alias — rinominare le colonne nel risultato

Quando usi funzioni di aggregazione, la colonna nel risultato avrebbe un nome tecnico brutto (es. «Conteggio di Descrizione»). Con l'Alias puoi darle un nome chiaro.

Clicca sulla cella della riga Alias nella colonna che vuoi rinominare.
Scrivi il nome che vuoi venga mostrato come intestazione colonna, es. NUM PRODOTTI.
Esegui la query: il risultato mostrerà il tuo alias come intestazione.
💡
L'alias funziona sempre, non solo con le aggregazioni. Puoi usarlo per rinominare qualsiasi campo — ad esempio mostrare «Fornitore» invece di «Ragione_Sociale».
10

Query su più tabelle (JOIN)

Quando aggiungi più tabelle collegate al Query Designer, LibreOffice traccia automaticamente le linee di join tra di esse (le stesse linee della struttura relazioni). Non devi fare nulla di speciale: basta che le tabelle siano effettivamente collegate nel database.

Più tabelle con join nel pannello superiore
Schermata reale — 4 tabelle collegate: FORNITORE → CATALOGO_FORNITORE → PRODOTTO → TIPOLOGIA. Le linee mostrano i join.

Come aggiungere le tabelle giuste

Prima di aprire il designer, pensa a quali informazioni ti servono e in quali tabelle si trovano.
Traccia mentalmente il "percorso" tra le tabelle seguendo le relazioni. Es: per avere Ragione_Sociale + Descrizione prodotto devo passare da FORNITORE → CATALOGO_FORNITORE → PRODOTTO.
Aggiungi solo le tabelle nel percorso. Se hai bisogno anche della Tipologia, aggiungi anche TIPOLOGIA (è collegata a PRODOTTO).
Verifica che le linee di join siano visibili tra tutte le tabelle aggiunte. Se manca una linea, probabilmente hai aggiunto una tabella non collegata alle altre.
🚫
Prodotto cartesiano — il nemico numero uno! Se aggiungi una tabella senza collegamento alle altre, il database moltiplica ogni riga di quella tabella per ogni riga delle altre. Una tabella con 10 righe e un'altra con 100 righe producono 1.000 righe spesso senza senso. Riconosci il prodotto cartesiano dai numeri assurdi di record nel risultato.

Riepilogo visivo — cosa controllare sempre

Cosa controllare✅ Corretto❌ Sbagliato
Linee di joinTutte le tabelle hanno almeno una linea che le collegaUna tabella "flotta" da sola
Riga TabellaOgni campo mostra la tabella correttaCampo da tabella sbagliata
Numero recordPlausibile rispetto ai datiNumero altissimo e inaspettato
Funzione con aggregazioneOgni colonna ha Gruppo o una funzioneMix di colonne con e senza funzione
💡
Salva sempre con un nome parlante! Usa prefisso Q_ seguito da una descrizione: Q_CatalogoFornitori, Q_VenditeMensili. Così nella lista delle ricerche capisci subito a cosa serve ogni query.
11

Tipi di join — modificare le relazioni dall'interfaccia

Di default LibreOffice Base usa un INNER JOIN (Relazione interna): vengono restituiti solo i record che hanno una corrispondenza in entrambe le tabelle. Se vuoi includere anche i record senza corrispondenza — ad esempio scontrini di clienti non registrati — devi modificare il tipo di join direttamente sulla linea grafica.

Modificare il tipo di join dalla linea grafica

Nel pannello superiore del Query Designer, fai clic destro sulla linea che collega le due tabelle.
Nel menu contestuale scegli Modifica join… Si apre il dialog Proprietà delle relazioni.
Nel menu a tendina Tipo, seleziona il tipo di join desiderato (vedi tabella sotto).
Leggi la descrizione in fondo al dialog che spiega in italiano cosa farà il join scelto, poi clicca OK.
Dialog Proprietà delle relazioni con dropdown aperto sui 4 tipi di join
Schermata reale — Dialog «Proprietà delle relazioni»: il menu Tipo mostra i 4 tipi disponibili. La descrizione in fondo cambia in tempo reale e spiega in italiano cosa farà il join selezionato.
Tipo (LibreOffice)Equivalente SQLRestituisceQuando usarlo
Relazione internaINNER JOINSolo le righe con corrispondenza in entrambe le tabelleCaso standard — vuoi solo dati completi
Relazione sinistraLEFT JOINTutte le righe della tabella di sinistra + corrispondenze a destra (NULL se mancano)Vuoi tutti i record della tabella principale, anche senza corrispondenza
Relazione destraRIGHT JOINTutte le righe della tabella di destra + corrispondenze a sinistra (NULL se mancano)Speculare al LEFT — la tabella "completa" è quella di destra
Relazione incrociataFULL OUTER JOINTutte le righe di entrambe le tabelle, con NULL dove manca la corrispondenzaRaro; alcuni database non lo supportano (nota nel dialog)
ℹ️
Come capire quale tabella è "sinistra" e quale è "destra"? Nel pannello superiore del designer, la tabella da cui parte la linea di join è quella di sinistra; quella in cui arriva è quella di destra. LibreOffice indica anche i nomi esatti nel campo «Tabelle considerate» del dialog.

Esempio pratico — RIGHT JOIN tra SCONTRINO e CLIENTE

Vogliamo il catalogo completo delle vendite: per ogni riga di DETTAGLIO_VENDITE vogliamo vedere il prodotto, la quantità, il prezzo e — se disponibile — il codice fiscale del cliente. Gli scontrini anonimi (senza CF_Cliente) devono comparire ugualmente.

Griglia criteri della query catalogo vendite con 5 tabelle
Griglia criteri — 5 tabelle: CLIENTE (RIGHT JOIN) · SCONTRINO · TIPOLOGIA · PRODOTTO · DETTAGLIO_VENDITE. Alias usati per i titoli di colonna; ordinamento crescente su Categoria Merceologica e decrescente su Qta; criterio TRA 1 E 5 sul campo Prezzo_Listino.

// Configurazione della query nell'esempio:

  • Join CLIENTE ↔ SCONTRINO: impostato a Relazione destra (RIGHT JOIN) — tutti gli scontrini compaiono, anche quelli senza cliente registrato
  • Alias colonne: Descrizione della TIPOLOGIA → «Categoria Merceologica»; Descrizione di PRODOTTO → «Desc. Prodotto»; EAN → «Codice Prodotto»; Qta → «Numero pezzi»
  • Ordinamenti: Categoria Merceologica crescente · Numero pezzi decrescente
  • Criterio: TRA 1 E 5 su Prezzo_Listino — solo prodotti con prezzo compreso tra 1 € e 5 €
Output della query con righe a CF_CLIENTE vuoto per scontrini anonimi
Output reale — Le righe con CF_CLIENTE vuoto sono scontrini di clienti non registrati: grazie al RIGHT JOIN compaiono ugualmente nel risultato invece di essere esclusi. Senza il cambio di tipo di join, queste righe sarebbero invisibili.
12

Relazioni in cascata

Le relazioni tra tabelle non servono solo a collegare i dati nelle query — definiscono anche cosa succede quando si modifica o si cancella un record padre. Questo si gestisce dalla finestra Struttura relazioni, facendo doppio clic sulla linea di join tra due tabelle.

Aprire il dialog della relazione

Dal menu principale di LibreOffice Base, vai su Strumenti → Relazioni.
Nella finestra che si apre, fai doppio clic sulla linea che collega due tabelle.
Si apre il dialog Relazioni con le opzioni di aggiornamento ed eliminazione.
Dialog Relazioni con opzioni cascata
Schermata reale — Dialog Relazioni tra PRODOTTO e TIPOLOGIA: opzioni di aggiornamento ed eliminazione

Le opzioni disponibili

OpzioneCosa succede al record figlio quando il padre cambia
Nessuna operazioneNon succede nulla — ma se il padre viene modificato/cancellato, il database può bloccare l'operazione per mantenere l'integrità
Aggiorna/Elimina cascataLa modifica o cancellazione si propaga automaticamente a tutti i record figli collegati
Imposta NULLIl campo chiave esterna nei record figli viene impostato a NULL (campo vuoto)
Imposta predefinitoIl campo chiave esterna viene impostato al valore predefinito della colonna

Esempio pratico — Aggiorna cascata

Scenario: nella tabella TIPOLOGIA cambiamo il codice CASA in CASA2. Con Aggiorna cascata attivo, tutti i prodotti che avevano FK_COD_Tipo = 'CASA' vengono aggiornati automaticamente a 'CASA2' — senza dover toccare manualmente la tabella PRODOTTO.

// Senza cascata vs Con cascata:

  • Senza cascata: modificare o cancellare un record padre con figli collegati → errore di integrità referenziale, operazione bloccata
  • Con Aggiorna cascata: modifichi il padre → i figli si aggiornano automaticamente
  • Con Elimina cascata: cancelli il padre → tutti i figli vengono cancellati automaticamente
⚠️
Elimina cascata — usare con cautela! Se cancelli una TIPOLOGIA con Elimina cascata attivo, vengono cancellati automaticamente tutti i PRODOTTI collegati. L'operazione non è reversibile. Assicurati sempre di sapere quanti record figlio verranno eliminati prima di procedere.

Modificare i dati direttamente da tabella

Per modificare o cancellare record senza SQL, LibreOffice Base permette di lavorare direttamente nella vista tabella:

Nel pannello sinistro, clicca su Tabelle.
Fai doppio clic sul nome della tabella che vuoi modificare.
Clicca sulla cella che vuoi modificare, digita il nuovo valore e premi Invio o spostati su un'altra riga per confermare.
Per cancellare una riga: selezionala cliccando sul quadratino a sinistra → tasto Canc → conferma.

Esempio reale — Elimina cascata + Imposta NULL a confronto

Lo stesso evento — cancellare un cliente — può avere effetti diversi su tabelle diverse, a seconda di come è configurata ogni relazione. Nell'esempio seguente il database gestisce tre tabelle collegate a CLIENTE: TESSERA e SCONTRINO.

// Scenario: cancello il cliente Rossi Mario (CF: RSSMRA80A01H501Z)

  • TESSERA → Elimina cascata: la tessera fedeltà di Rossi viene cancellata automaticamente. Non ha senso conservarla senza il cliente a cui appartiene.
  • SCONTRINO → Imposta NULL: gli scontrini di Rossi rimangono nel sistema — sono dati fiscali e storici da preservare — ma il campo FK_CF_Cliente viene impostato a NULL. Lo scontrino esiste ancora, ma non è più attribuito a nessun cliente.
Dialog Relazioni TESSERA–CLIENTE con Elimina cascata
Relazione TESSERA → CLIENTE — Elimina cascata attivo: cancellando il cliente, la tessera viene eliminata automaticamente.
Dialog Relazioni SCONTRINO–CLIENTE con Imposta NULL
Relazione SCONTRINO → CLIENTE — Imposta NULL attivo: cancellando il cliente, gli scontrini restano ma FK_CF_Cliente diventa NULL.
💡
Regola pratica: usa Elimina cascata quando il record figlio non ha senso senza il padre (tessera senza cliente). Usa Imposta NULL quando il dato figlio va conservato anche dopo la cancellazione del padre (scontrino come dato storico/fiscale).
💡
La cascata fa il lavoro sporco. Se le relazioni sono configurate correttamente con Aggiorna/Elimina cascata, puoi modificare o cancellare record padre direttamente dalla vista tabella — il database propagherà le modifiche ai figli in automatico.
13

Query calcolate e raggruppamento

Nelle query che coinvolgono calcoli tra campi, il campo non è una colonna della tabella ma un'espressione matematica da inserire direttamente nella riga Campo del QBE. L'alias assegnato nella riga Alias diventa il nome della colonna nel risultato.

Caso 1 — Totale venduto per prodotto

Vogliamo sapere quanto ha reso ogni prodotto: moltiplichiamo il prezzo di listino per la quantità venduta, raggruppando per descrizione del prodotto.

Aggiungi le tabelle PRODOTTO e DETTAGLIO_VENDITA al designer.
Nella riga Campo, inserisci l'espressione: "PRODOTTO"."Prezzo_Listino" * "DETTAGLIO_VENDITA"."Qta"
Nella riga Alias, scrivi: Totale per prodotto
Per il campo Descrizione imposta Funzione → Gruppo; per l'espressione calcolata imposta Funzione → Somma.
QBE query calcolata — totale per prodotto
QBE — L'espressione matematica nel campo, alias "Totale per prodotto", Funzione Gruppo su Descrizione e Somma sull'espressione.
Risultato query — totale venduto per prodotto
Risultato — ogni riga riporta un prodotto con il totale delle vendite calcolato.

Caso 2 — Totale per scontrino

La stessa espressione matematica può essere usata per rispondere a una domanda diversa: quanto vale ogni singolo scontrino? Basta cambiare la dimensione di raggruppamento — non la formula.

Aggiungi anche la tabella SCONTRINO al designer.
Usa la stessa espressione: "PRODOTTO"."Prezzo_Listino" * "DETTAGLIO_VENDITA"."Qta" con alias Totale scontrino
Imposta Funzione → Gruppo su ID_Scontrino e NUM_Scontrino; Funzione → Somma sull'espressione calcolata.
QBE query calcolata — totale per scontrino
QBE — Stessa espressione, raggruppamento su ID_Scontrino e NUM_Scontrino.
Risultato query — totale per scontrino
Risultato — ogni riga riporta uno scontrino con il proprio totale.

// Formula invariante, significato variabile:

  • L'espressione matematica non cambiaPrezzo_Listino × Qta è sempre la stessa.
  • È la dimensione di raggruppamento a determinare il dato: raggruppo per prodotto → totale per articolo; raggruppo per scontrino → totale per transazione.
  • Questo principio è alla base di qualsiasi analisi dati: stessa misura, granularità diversa, risposta diversa.
14

Estendere un database esistente

Un database in produzione — già popolato di dati — può richiedere modifiche strutturali: nuove tabelle, nuove relazioni, nuovi vincoli. L'obiettivo è preservare i dati esistenti e le regole di integrità già in vigore, senza dover ricostruire tutto da zero.

⚠️
Prima di modificare la struttura: fai sempre un backup del file .odb. Le modifiche alla struttura non sono reversibili con Annulla.

Caso d'uso — Normalizzare il metodo di pagamento

Nella tabella SCONTRINO il campo Metodo_Pagamento contiene testo libero: Contanti, Carta, Satispay. Vogliamo trasformarlo in una chiave esterna verso una nuova tabella di decodifica, così da garantire coerenza e poter aggiungere informazioni al metodo (es. commissione applicata).

Passo 0 — Situazione di partenza

La tabella SCONTRINO contiene già dati. Il campo Metodo_Pagamento è testo libero — nessun vincolo impedisce valori incoerenti o errori di battitura.

Tabella SCONTRINO con dati — Metodo_Pagamento testo libero
Schermata reale — Tabella SCONTRINO: il campo Metodo_Pagamento contiene testo libero. Tre valori distinti in uso: Contanti, Carta, Satispay.

Passo 1 — Preparare il campo esistente

Prima di istituire la relazione, il campo Metodo_Pagamento deve essere impostato come NOT NULL — obbligatorio. Apri la struttura della tabella SCONTRINO e imposta Digitazione necessaria su .

Struttura tabella SCONTRINO — Digitazione necessaria impostata a Sì
Schermata reale — Proprietà del campo Metodo_Pagamento: Digitazione necessaria = Sì. Da questo momento il campo non può essere vuoto.

Passo 2 — Individuare i valori già in uso

Prima di creare la nuova tabella, è necessario conoscere tutti e soli i valori già presenti nel campo. Apri il designer delle query e crea una query di raggruppamento su Metodo_Pagamento dalla tabella SCONTRINO.

Query di raggruppamento su Metodo_Pagamento — risultato: Carta, Contanti, Satispay
Schermata reale — Query di raggruppamento: i tre valori distinti già presenti negli scontrini. Questi valori devono essere presenti nella nuova tabella come PK.
💡
Perché il raggruppamento? Con molti record è impossibile scorrere la tabella manualmente. Il raggruppamento restituisce ogni valore una sola volta, qualunque sia il numero di scontrini.

Passo 3 — Creare la tabella di decodifica

Crea la nuova tabella METODI_PAGAMENTO con COD_METODO come chiave primaria. Inserisci almeno i valori già presenti negli scontrini — puoi aggiungerne altri se prevedi metodi futuri.

Tabella METODI_PAGAMENTO con COD_METODO, DESC_METODO e COMMISSIONE
Schermata reale — La nuova tabella METODI_PAGAMENTO. I valori già usati negli scontrini (Carta, Contanti, Satispay) sono presenti come PK. Paypal e Bonifico vengono aggiunti in anticipo.
⚠️
Attenzione ai valori mancanti. Se negli scontrini esiste un valore che non è presente nella nuova tabella, la relazione non potrà essere istituita — il database segnala una violazione di integrità referenziale. Il raggruppamento del Passo 2 serve proprio a evitare questo problema.

Passo 4 — Istituire la relazione

Vai su Strumenti → Relazioni, aggiungi entrambe le tabelle e collega SCONTRINO.Metodo_Pagamento a METODI_PAGAMENTO.COD_METODO. Configura le opzioni in base alle regole di business:

Dialog Relazioni SCONTRINO–METODI_PAGAMENTO con Aggiorna cascata e Nessuna operazione per eliminazione
Schermata reale — Relazione SCONTRINO → METODI_PAGAMENTO. Aggiorna cascata: se il codice metodo cambia, si aggiorna automaticamente in tutti gli scontrini. Nessuna operazione per eliminazione: non è possibile cancellare un metodo se esistono scontrini collegati.
Opzione sceltaMotivazione
Aggiorna cascataSe il codice di un metodo viene rinominato, tutti gli scontrini si aggiornano automaticamente
Nessuna operazione (eliminazione)Non si può cancellare un metodo di pagamento se esistono scontrini che lo usano — il database blocca l'operazione

Risultato

Da questo momento il campo Metodo_Pagamento in SCONTRINO è una chiave esterna verso METODI_PAGAMENTO. Ogni nuovo scontrino dovrà obbligatoriamente indicare un metodo tra quelli presenti nella tabella di decodifica — valori non previsti verranno rifiutati dal database.

// Prima vs Dopo:

  • Prima: testo libero — nessun controllo, possibili errori di battitura, valori incoerenti tra record
  • Dopo: chiave esterna NOT NULL — solo valori ammessi, coerenza garantita, possibilità di aggiungere attributi al metodo (descrizione, commissione, attivo/disattivo)