In SQL, i connettivi logici AND, OR e NOT sono strumenti fondamentali per combinare e filtrare condizioni all’interno di una query. Questi connettivi permettono di costruire espressioni complesse che definiscono in modo preciso quali righe devono essere restituite da una query.

AND

Il connettivo AND viene utilizzato quando più condizioni devono essere tutte vere affinché una riga venga restituita. Consideriamo l'esempio seguente:

sql
SELECT InvoiceNo, SaleDate, SalesPerson, TotalSale
FROM SALES WHERE SaleDate >= '2019-01-16' AND SaleDate <= '2019-01-22';

In questo caso, la clausola WHERE impone due condizioni: la data di vendita deve essere maggiore o uguale al 16 gennaio 2019 e minore o uguale al 22 gennaio 2019. Solo le righe che soddisfano entrambe queste condizioni verranno restituite dalla query. La logica del connettivo AND è molto precisa e può a volte sembrare rigida, specialmente quando il linguaggio naturale è meno stringente. Ad esempio, se il tuo capo ti chiede di vedere le vendite per due persone, Acheson e Bryant, e scrivi la query:

sql
SELECT * FROM SALES WHERE Salesperson = 'Acheson' AND Salesperson = 'Bryant';

Questa query non restituirà alcun risultato, perché non esiste nessuna riga in cui la stessa vendita sia stata effettuata sia da Acheson che da Bryant. La query corretta sarebbe:

sql
SELECT *
FROM SALES WHERE Salesperson IN ('Acheson', 'Bryant');

Questa versione restituirà tutte le vendite effettuate da Acheson o Bryant, che è probabilmente ciò che il tuo capo voleva.

OR

Il connettivo OR viene utilizzato quando basta che una delle condizioni sia vera affinché una riga venga restituita. Ad esempio:

sql
SELECT InvoiceNo, SaleDate, Salesperson, TotalSale
FROM SALES WHERE Salesperson = 'Bryant' OR TotalSale > 200;

Questa query restituirà tutte le vendite effettuate da Bryant, indipendentemente dall’importo, e tutte le vendite superiori a 200, indipendentemente da chi le ha effettuate. Il connettivo OR consente una maggiore flessibilità, poiché basta che una delle condizioni sia soddisfatta.

NOT

Il connettivo NOT inverte il risultato di una condizione. Se una condizione normalmente restituirebbe TRUE, l’aggiunta di NOT la trasforma in FALSE. Se la condizione sarebbe normalmente FALSE, l’aggiunta di NOT la rende TRUE. Consideriamo questo esempio:

sql
SELECT InvoiceNo, SaleDate, Salesperson, TotalSale FROM SALES WHERE NOT (Salesperson = 'Bryant');

Questa query restituirà tutte le vendite effettuate da persone diverse da Bryant. In questo caso, il connettivo NOT agisce invertendo la condizione, restituendo così tutte le righe dove la persona non è Bryant.

L’importanza delle parentesi

Quando si utilizzano AND, OR o NOT in una query SQL, è cruciale essere precisi nell’applicazione delle condizioni. Talvolta, la portata del connettivo non è chiara e l'uso delle parentesi può evitare errori. Ad esempio:

sql
SELECT InvoiceNo, SaleDate, Salesperson, TotalSale
FROM SALES WHERE NOT (Salesperson = 'Bryant' AND TotalSale > 200);

In questo caso, l’intera condizione Salesperson = 'Bryant' AND TotalSale > 200 è negata, quindi la query restituirà tutte le righe dove Bryant non ha effettuato vendite superiori a 200.

Funzioni di aggregazione con GROUP BY

Oltre a filtrare i dati, spesso è necessario analizzare gruppi di righe anziché singole righe. Per farlo, si utilizza la clausola GROUP BY insieme alle funzioni di aggregazione come AVG (media), SUM (somma), COUNT (conteggio), etc. Queste funzioni permettono di ottenere informazioni più significative da grandi quantità di dati.

Ad esempio, supponiamo che si voglia analizzare le vendite di un mese per singolo venditore. Una query che utilizza AVG per calcolare la media delle vendite potrebbe apparire come segue:

sql
SELECT LastName, AVG(TotalDue)
FROM Sales.SalesOrderHeader, Person.Person WHERE BusinessEntityID = SalesPersonID AND OrderDate >= '2011-05-01' AND OrderDate < '2011-05-31' GROUP BY LastName;

Questa query raggruppa le righe per cognome del venditore e calcola la media delle vendite totali per ogni venditore nel periodo specificato. La clausola GROUP BY ordina i risultati in ordine alfabetico per LastName, mentre la funzione AVG restituisce la media delle vendite per ciascun venditore.

In alternativa, per analizzare il totale delle vendite per ogni venditore, si può usare la funzione SUM:

sql
SELECT LastName, SUM(TotalDue)
FROM Sales.SalesOrderHeader, Person.Person WHERE BusinessEntityID = SalesPersonID AND OrderDate >= '2011-05-01' AND OrderDate < '2011-05-31' GROUP BY LastName;

Questa query fornirà il totale delle vendite per ciascun venditore nel mese di maggio 2011.

Filtrare i gruppi con HAVING

Quando si utilizzano le funzioni di aggregazione, è possibile che i dati restituiti contengano gruppi che non sono rilevanti per l'analisi. In questi casi, si può utilizzare la clausola HAVING per filtrare i gruppi dopo che sono stati creati. Ad esempio, se si desidera escludere dalle analisi un venditore specifico, come Saraiva, si può usare la seguente query:

sql
SELECT LastName, SUM(TotalDue)
FROM Sales.SalesOrderHeader, Person.Person WHERE BusinessEntityID = SalesPersonID AND OrderDate >= '2011-05-01' AND OrderDate < '2011-05-31' GROUP BY LastName HAVING LastName <> 'Saraiva';

In questo caso, la clausola HAVING filtra i gruppi di vendite in modo che non venga incluso il venditore Saraiva nei risultati, pur mantenendo gli altri venditori.

Ordinamento dei risultati con ORDER BY

Infine, per organizzare i risultati in un ordine specifico, si utilizza la clausola ORDER BY. Mentre la clausola GROUP BY raggruppa i dati, ORDER BY ordina i risultati. Si può scegliere di ordinare i dati in ordine crescente o decrescente, a seconda delle necessità analitiche. Per esempio:

sql
SELECT LastName, SUM(TotalDue)
FROM Sales.SalesOrderHeader, Person.Person WHERE BusinessEntityID = SalesPersonID AND OrderDate >= '2011-05-01' AND OrderDate < '2011-05-31' GROUP BY LastName ORDER BY SUM(TotalDue) DESC;

Questa query ordina i venditori in ordine decrescente in base al totale delle vendite, consentendo di identificare facilmente chi ha ottenuto il miglior risultato.


Le funzioni di aggregazione, la corretta applicazione dei connettivi logici, e l'uso di clausole come HAVING e ORDER BY sono fondamentali per analizzare e comprendere in modo approfondito grandi volumi di dati. A prescindere dall'abilità di scrivere query complesse, è cruciale capire le implicazioni logiche di ogni connettivo e funzione utilizzata, per evitare errori e ottenere risultati precisi e utili per le decisioni aziendali.

Come creare e utilizzare funzioni in R: fondamenti e applicazioni

R è un linguaggio di programmazione potente che offre una vasta gamma di funzioni per gestire e analizzare dati. Una delle caratteristiche più utili di R è la possibilità di creare le proprie funzioni, che possono semplificare operazioni ripetitive e personalizzare il flusso di lavoro. In questa sezione, esploreremo come definire una funzione in R, utilizzarla e commentare il codice, e vedremo anche alcuni concetti fondamentali come vettori, matrici e liste.

La sintassi di una funzione in R è la seguente:

r
myfunction <- function(argument1, argument2, ...){ statements return(object) }

Un esempio semplice di funzione in R è quella che calcola l'ipotenusa di un triangolo rettangolo, utilizzando il celebre teorema di Pitagora. Supponiamo di avere due cateti di un triangolo con lunghezze a e b, la funzione per calcolare l'ipotenusa c sarà:

r
hypotenuse <- function(a,b){ hyp <- sqrt(a^2 + b^2) return(hyp) }

Per utilizzare questa funzione, basta passare i valori dei cateti:

r
hypotenuse(3,4)
[1] 5

Una volta che la funzione è stata definita, possiamo invocarla per ottenere il risultato desiderato. La sintassi sqrt(a^2 + b^2) calcola la radice quadrata della somma dei quadrati dei due cateti, che corrisponde appunto alla lunghezza dell'ipotenusa.

In R, è possibile anche aggiungere commenti al codice per migliorare la leggibilità e spiegare il funzionamento delle varie parti. I commenti iniziano con il simbolo # e R ignora tutto il testo a destra di questo simbolo. Ecco un esempio di codice con commenti:

r
hypotenuse <- function(a,b){ # calcola l'ipotenusa
hyp <- sqrt(a^2 + b^2) # applica il teorema di Pitagora return(hyp) # restituisce il valore dell'ipotenusa }

I commenti sono fondamentali per chi deve leggere o modificare il codice, in quanto spiegano il funzionamento delle varie operazioni.

Un altro concetto fondamentale in R è il vettore, che rappresenta una sequenza di elementi dello stesso tipo. In R, i vettori sono uno degli oggetti più comuni. Per creare un vettore, si utilizza la funzione c(). Ad esempio, il seguente codice crea un vettore di numeri:

r
x <- c(5,10,15,20,25,30,35,40)

Per lavorare con vettori di caratteri, è sufficiente racchiudere le stringhe tra virgolette:

r
beatles <- c("john","paul","george","ringo")

È anche possibile avere un vettore logico, che contiene valori TRUE o FALSE:

r
w <- c(T,F,F,T,T,F)

Per accedere a un elemento specifico del vettore, si utilizza l'indice tra parentesi quadre:

r
beatles[2]
[1] "paul"

R consente anche di selezionare un intervallo di elementi utilizzando i due punti ::

r
beatles[2:3]
[1] "paul" "george"

Inoltre, è possibile fare riferimento a componenti non consecutive tramite la funzione c():

r
beatles[c(2,4)]
[1] "paul" "ringo"

Un altro modo per creare sequenze numeriche è utilizzare la funzione seq(). Ad esempio, la seguente funzione crea una sequenza da 5 a 40 con intervalli di 5 unità:

r
y <- seq(5,40,5)

Senza il terzo argomento, la sequenza aumenterà di 1 per default:

r
y <- seq(5,40)

Un'altra funzione utile è rep(), che crea un vettore di valori ripetuti. Ecco un esempio:

r
quadrifecta <- c(7,8,4,3)
repeated_quadrifecta <- rep(quadrifecta, 3)

Questa funzione ripete il vettore tre volte, creando una sequenza del tipo:

r
[1] 7 8 4 3 7 8 4 3 7 8 4 3

Per aggiungere un elemento alla fine di un vettore, si utilizza la funzione append():

r
xx <- c(3,4,5)
xx <- append(xx,6)

Un concetto importante in R è la matrice, che rappresenta una struttura bidimensionale di dati dello stesso tipo. Per creare una matrice, è necessario innanzitutto definire un vettore e poi utilizzare la funzione dim() per trasformarlo in una matrice. Ad esempio, supponiamo di voler creare una matrice 5x4 di numeri:

r
num_matrix <- seq(5,100,5) dim(num_matrix) <- c(5,4)

La matrice risultante avrà la seguente forma:

r
[,1] [,2] [,3] [,4]
[1,] 5 30 55 80 [2,] 10 35 60 85 [3,] 15 40 65 90 [4,] 20 45 70 95 [5,] 25 50 75 100

In R, le matrici sono sempre riempite per colonne per default. Tuttavia, è possibile modificare questo comportamento usando l'argomento byrow=T nella funzione matrix().

R consente anche di riferirsi a specifici componenti di una matrice usando la notazione di riga e colonna, come nel seguente esempio:

r
num_matrix[5,4] [1] 100

Infine, le liste in R sono raccolte di oggetti che non devono necessariamente essere dello stesso tipo. Ad esempio, se si desidera raccogliere informazioni sui Beatles, si potrebbe creare una lista contenente sia i nomi dei membri che la loro età al momento dell'ingresso nel gruppo:

r
beatles <- c("john","paul","george","ringo") ages <- c(17,15,14,22) beatles_info <- list(names=beatles, age_joined=ages)

Le liste sono molto utili quando si desidera memorizzare oggetti di diversi tipi insieme.

Concludendo, capire come funzionano i vettori, le matrici e le liste è fondamentale per utilizzare R in modo efficace. Questi concetti sono alla base di molte operazioni in R, dalla manipolazione dei dati all'analisi statistica. Inoltre, comprendere la creazione e l'utilizzo di funzioni personalizzate consente di scrivere codice più leggibile ed efficiente, fondamentale per gestire progetti complessi e per lavorare in team.

Come funziona la creazione di storie e visualizzazioni dati in Tableau?

Tableau offre un ambiente potente per trasformare dati complessi in narrazioni visive chiare e coinvolgenti. La distinzione tra fogli di lavoro e cartelle di lavoro è fondamentale: un foglio rappresenta una singola visualizzazione, mentre una cartella di lavoro ne raccoglie molteplici, permettendo di organizzare e gestire dati con efficienza. Rinominare e cancellare fogli è una pratica utile per mantenere ordine e chiarezza durante l’analisi.

Lavorare con i dashboard è un passaggio cruciale per aggregare e configurare diverse visualizzazioni, personalizzandole in base alle esigenze del progetto. È possibile aggiungere oggetti vari — grafici, mappe, tabelle, elementi testuali — per arricchire la storia visiva, creando un’esperienza interattiva e dinamica. La personalizzazione del dashboard consente di enfatizzare i dati più rilevanti e di guidare l’attenzione dell’utente verso le conclusioni desiderate.

La creazione di una storia coinvolgente in Tableau richiede un’attenta pianificazione. Prima di tutto, bisogna definire lo scopo e il messaggio centrale, selezionando i dati da sintetizzare in modo coerente. L’ambiente di lavoro per le storie permette di combinare fogli e dashboard in sequenze narrative, che facilitano la comprensione progressiva delle informazioni. Ogni “scena” della storia deve essere costruita con cura, bilanciando contenuto e forma per mantenere l’interesse e la chiarezza.

Il formato della storia è un elemento altrettanto importante: scegliere colori, dimensioni e posizionamenti non è solo questione estetica, ma di comunicazione efficace. La coerenza visiva e l’uso sapiente degli spazi contribuiscono a rendere il messaggio più immediato e memorabile.

Tableau propone una vasta gamma di visualizzazioni, ognuna adatta a diversi tipi di dati e scopi analitici. Dalle tabelle testuali alle mappe con o senza simboli, passando per grafici a torta, barre, linee, scatter plot e diagrammi a cascata, ogni visualizzazione ha la sua funzione specifica nel raccontare una parte della storia. Saper scegliere la giusta tipologia grafica è essenziale per valorizzare i dati e rendere trasparente la loro interpretazione.

La possibilità di convertire visualizzazioni in tabelle pivot permette una doppia lettura dei dati, agevolando chi preferisce un approccio più tradizionale all’analisi. La pubblicazione delle visualizzazioni, infine, consente la condivisione e la collaborazione, integrandosi con piattaforme cloud come Tableau Cloud che facilitano l’accesso, il confronto e l’aggiornamento in tempo reale.

Oltre a quanto descritto, è importante comprendere come la narrazione visiva in Tableau non sia solo un esercizio tecnico, ma un’arte che richiede sensibilità e strategia. Ogni scelta grafica deve rispondere a un’esigenza comunicativa precisa e non essere fine a sé stessa. La capacità di sintetizzare grandi quantità di dati in storie accessibili è ciò che distingue un buon analista da un comunicatore di dati efficace. Inoltre, bisogna saper adattare la narrazione al pubblico di riferimento, modulando il livello di dettaglio e la complessità visiva per massimizzare l’impatto e la comprensione.

Infine, la consapevolezza dell’importanza dell’interattività — offrendo all’utente la possibilità di esplorare i dati in modo autonomo attraverso filtri e selezioni — rappresenta una chiave per potenziare il coinvolgimento e la profondità dell’analisi, andando oltre una semplice presentazione statica.