<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Nicola Iantomasi</title>
    <description>The latest articles on Forem by Nicola Iantomasi (@nicola-iantomasi).</description>
    <link>https://forem.com/nicola-iantomasi</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1183082%2F694fb2b9-0051-4833-93e7-e1e33c8fa52f.JPG</url>
      <title>Forem: Nicola Iantomasi</title>
      <link>https://forem.com/nicola-iantomasi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/nicola-iantomasi"/>
    <language>en</language>
    <item>
      <title>T-SQL avanzato: tecniche da ricordare</title>
      <dc:creator>Nicola Iantomasi</dc:creator>
      <pubDate>Sat, 21 Dec 2024 09:26:50 +0000</pubDate>
      <link>https://forem.com/nicola-iantomasi/t-sql-avanzato-tecniche-da-ricordare-2hni</link>
      <guid>https://forem.com/nicola-iantomasi/t-sql-avanzato-tecniche-da-ricordare-2hni</guid>
      <description>&lt;p&gt;In SQL Server, padroneggiare le tecniche avanzate di T-SQL è fondamentale per sviluppare applicazioni database efficienti e manutenibili. In questo articolo approfondito, esploreremo alcune delle funzionalità più potenti di T-SQL, con esempi pratici e spiegazioni dettagliate. Per approfondimenti e altri articoli tecnici su SQL Server, vi invito a visitare il mio sito su SQL Server &lt;a href="//www.nicolaiantomasi.com"&gt;www.nicolaiantomasi.com&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Gestione Avanzata dei NULL nelle JOIN
&lt;/h2&gt;

&lt;p&gt;Uno degli aspetti più sottovalutati di T-SQL è la corretta gestione dei NULL nelle operazioni di JOIN. Consideriamo un esempio pratico:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE TABLE dbo.Magazzino(
    Codice1 VARCHAR(5),
    Codice2 VARCHAR(5),
    Nome VARCHAR(50)
);

CREATE TABLE dbo.Prezzario(
    Codice1 VARCHAR(5),
    Codice2 VARCHAR(5),
    Prezzo DECIMAL(18,4)
);

-- Dati di esempio con NULL intenzionali
INSERT INTO dbo.Magazzino VALUES 
    ('A1', 'B1', 'Prodotto1'),
    ('A1', 'B2', 'Prodotto2'),
    ('A2', NULL, 'Prodotto3');

INSERT INTO dbo.Prezzario VALUES 
    ('A1', 'B1', 3.24),
    ('A2', NULL, 1.4);`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Una comune svista è pensare che questa query funzioni correttamente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT * 
FROM dbo.Magazzino m
INNER JOIN dbo.Prezzario p 
    ON m.Codice1 = p.Codice1 
    AND m.Codice2 = p.Codice2;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Il problema? In SQL, NULL = NULL restituisce NULL, non TRUE. La soluzione corretta è:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT * 
FROM dbo.Magazzino m
INNER JOIN dbo.Prezzario p 
    ON m.Codice1 = p.Codice1 
    AND (m.Codice2 = p.Codice2 OR 
        (m.Codice2 IS NULL AND p.Codice2 IS NULL));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Questa query gestisce correttamente i casi in cui Codice2 è NULL in entrambe le tabelle, un requisito comune in applicazioni reali.&lt;/p&gt;

&lt;h2&gt;
  
  
  Window Functions: Oltre il GROUP BY
&lt;/h2&gt;

&lt;p&gt;Le Window Functions sono uno degli strumenti più potenti di T-SQL moderno. Permettono calcoli sofisticati mantenendo il dettaglio dei dati originali. Vediamo alcuni esempi pratici:&lt;br&gt;
Calcolo di Totali Progressivi&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;WITH Vendite AS (
    SELECT * FROM (VALUES
        ('2024-01-01', 1000),
        ('2024-01-02', 1500),
        ('2024-01-03', 800)
    ) v(Data, Importo)
)
SELECT 
    Data,
    Importo,
    SUM(Importo) OVER (
        ORDER BY Data 
    ) AS TotaleProgressivo,
    SUM(Importo) OVER () AS TotaleComplessivo,
    Importo * 100.0 / SUM(Importo) OVER () AS PercentualeSuTotale
FROM Vendite;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Questa query mostra diverse funzionalità:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Calcolo del totale progressivo giorno per giorno&lt;/li&gt;
&lt;li&gt;Calcolo del totale complessivo per confronto&lt;/li&gt;
&lt;li&gt;Calcolo della percentuale sul totale&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;La clausola OVER è fondamentale: definisce la "finestra" su cui operare. ROWS BETWEEN specifica l'intervallo di righe da considerare.&lt;br&gt;
Analisi Trend con LAG e LEAD&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT 
    Data,
    Importo,
    LAG(Importo) OVER (ORDER BY Data) AS ImportoPrecedente,
    LEAD(Importo) OVER (ORDER BY Data) AS ImportoSuccessivo,
    Importo - LAG(Importo) OVER (ORDER BY Data) AS Differenza,
    CASE 
        WHEN LAG(Importo) OVER (ORDER BY Data) IS NULL THEN NULL
        ELSE (Importo - LAG(Importo) OVER (ORDER BY Data)) * 100.0 / 
             LAG(Importo) OVER (ORDER BY Data)
    END AS VariazionePercentuale
FROM Vendite;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Questo codice illustra diverse funzionalità per l'analisi dei dati in sequenza temporale. In particolare, dimostra come la funzione LAG ci permetta di accedere ai valori delle righe precedenti nella sequenza, mentre LEAD ci consente di vedere i valori delle righe successive. Grazie a queste funzioni, possiamo facilmente calcolare sia le variazioni assolute che quelle percentuali tra diversi punti temporali dei nostri dati.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ranking e Partitioning
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;WITH VenditeClienti AS (
    SELECT * FROM (VALUES
        ('A', '2024-01-01', 1000),
        ('A', '2024-01-02', 1500),
        ('B', '2024-01-01', 800),
        ('B', '2024-01-02', 800)
    ) v(Cliente, Data, Importo)
)
SELECT 
    Cliente,
    Data,
    Importo,
    ROW_NUMBER() OVER (PARTITION BY Cliente ORDER BY Importo DESC) AS RigaNum,
    RANK() OVER (PARTITION BY Cliente ORDER BY Importo DESC) AS Rank,
    DENSE_RANK() OVER (PARTITION BY Cliente ORDER BY Importo DESC) AS DenseRank
FROM VenditeClienti;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Questo esempio mostra diversi modi di numerare e classificare i dati all'interno di partizioni. Innanzitutto, utilizzando PARTITION BY possiamo suddividere i nostri dati in sezioni separate per ogni cliente. Per quanto riguarda la numerazione, ROW_NUMBER ci fornisce una sequenza di numeri senza duplicati, anche se dobbiamo fare attenzione poiché in caso di valori identici l'ordine potrebbe non essere deterministico. Quando abbiamo bisogno di gestire i pari merito, possiamo utilizzare RANK, che lascerà dei "vuoti" nella numerazione in questi casi, oppure DENSE_RANK che invece mantiene una sequenza continua senza interruzioni.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pivot Dinamiche con SQL Dinamico
&lt;/h2&gt;

&lt;p&gt;Un uso avanzato di T-SQL è la creazione di pivot dinamiche. Invece di codificare staticamente le colonne:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DECLARE @cols NVARCHAR(MAX);
DECLARE @sql NVARCHAR(MAX);

SELECT @cols = STRING_AGG(QUOTENAME(Categoria), ',')
FROM (SELECT DISTINCT Categoria FROM Vendite) AS cats;

SET @sql = N'
SELECT *
FROM (
    SELECT Anno, Categoria, Importo
    FROM Vendite
) p
PIVOT (
    SUM(Importo) 
    FOR Categoria IN (' + @cols + ')
) AS pvt;';

EXEC sp_executesql @sql;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Punti chiave:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;QUOTENAME protegge da SQL injection&lt;/li&gt;
&lt;li&gt;STRING_AGG concatena i valori (sostituisce il vecchio XML PATH)&lt;/li&gt;
&lt;li&gt;sp_executesql esegue SQL dinamico in modo sicuro&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Il T-SQL avanzato richiede una comprensione profonda di come SQL Server elabora i dati. L'uso corretto di queste tecniche può migliorare significativamente sia la qualità che la manutenibilità del codice.&lt;/p&gt;

</description>
      <category>sql</category>
      <category>tsql</category>
      <category>database</category>
      <category>sqlserver</category>
    </item>
    <item>
      <title>SQL Server: Usare l'Istruzione LIKE all'Interno di una WHERE</title>
      <dc:creator>Nicola Iantomasi</dc:creator>
      <pubDate>Sun, 27 Oct 2024 15:26:54 +0000</pubDate>
      <link>https://forem.com/nicola-iantomasi/sql-server-usare-listruzione-like-allinterno-di-una-where-1cp7</link>
      <guid>https://forem.com/nicola-iantomasi/sql-server-usare-listruzione-like-allinterno-di-una-where-1cp7</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3q0f2gq2tz4mlepapoo4.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3q0f2gq2tz4mlepapoo4.jpg" alt="Image description" width="800" height="454"&gt;&lt;/a&gt;Il linguaggio &lt;strong&gt;SQL&lt;/strong&gt; offre potenti strumenti per filtrare i dati, e tra questi, la combinazione della clausola &lt;strong&gt;WHERE *&lt;em&gt;con l'istruzione **LIKE *&lt;/em&gt; si rivela particolarmente versatile per ricerche su colonne contenenti stringhe. Questo articolo esplora l'utilizzo di LIKE in SQL, con un focus particolare sulla sintassi T-SQL del database SQL Server, mostrando come filtrare dati basandosi **sull'inizio, il contenuto o la fine&lt;/strong&gt; di una stringa.&lt;/p&gt;

&lt;h2&gt;
  
  
  Utilizzo di LIKE all'Interno di una Condizione WHERE
&lt;/h2&gt;

&lt;p&gt;Esaminiamo tre scenari comuni: come estrarre prodotti il cui codice inizia, contiene, o termina con "XY". Le rispettive &lt;strong&gt;condizioni nella WHERE&lt;/strong&gt; saranno:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;WHERE CodiceProdotto LIKE 'XY%'&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;WHERE CodiceProdotto LIKE '%XY%'&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;WHERE CodiceProdotto LIKE '%XY'&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Il &lt;strong&gt;carattere %&lt;/strong&gt; funge da jolly, rappresentando qualsiasi numero di caratteri (incluso zero). È importante notare che la seconda condizione &lt;strong&gt;WHERE CodiceProdotto LIKE '%XY%'&lt;/strong&gt; cattura anche codici che iniziano o terminano con "XY".&lt;br&gt;
Per default, &lt;strong&gt;le ricerche su SQL Server non sono case-sensitive&lt;/strong&gt;, a meno che non si utilizzi la clausola &lt;strong&gt;COLLATE&lt;/strong&gt;.&lt;br&gt;
Per ricerche più sofisticate, SQL Server offre ulteriori operatori:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;WHERE CodiceProdotto LIKE '_XY%'&lt;/strong&gt; trova codici con "XY" in seconda e terza posizione.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;WHERE CodiceProdotto LIKE '[^A]%'&lt;/strong&gt; trova codici che non iniziano con "A".&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;WHERE CodiceProdotto LIKE '[AB]%[12]'&lt;/strong&gt; trova codici che iniziano con "A" o "B" e terminano con "1" o "2".&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Impatto sulle Performance dell'Utilizzo di LIKE in una WHERE
&lt;/h2&gt;

&lt;p&gt;Mentre è generalmente consigliato usare LIKE con moderazione per questioni di performance, esiste un caso d'uso frequente dove LIKE è la scelta ottimale: quando si cercano righe dove una colonna &lt;strong&gt;inizia con una specifica sequenza di caratteri&lt;/strong&gt;.&lt;br&gt;
Confrontiamo queste due query supponendo che sia presente un indice nonclustered sulla colonna CodiceProdotto:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;SELECT COUNT(*) &lt;br&gt;
FROM   dbo.Prodotti&lt;br&gt;
WHERE  LEFT(CodiceProdotto,2) = 'XY';&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;SELECT COUNT(*) &lt;br&gt;
FROM   dbo.Prodotti&lt;br&gt;
WHERE  CodiceProdotto LIKE 'XY%';&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Entrambe estraggono prodotti il cui codice inizia con "XY", ma la seconda query è significativamente più performante. Utilizzando W*&lt;em&gt;HERE CodiceProdotto LIKE 'XY%'&lt;/em&gt;&lt;em&gt;, il piano di esecuzione effettua una **ricerca ottimizzata&lt;/em&gt;* sull'indice (index seek), anziché una semplice scansione (index scan) come nella prima query.&lt;/p&gt;

&lt;p&gt;È cruciale notare che questo vantaggio non si applica a tutti gli usi di LIKE. Ad esempio, WHERE CodiceProdotto LIKE '%XY' risulterà in una scansione meno efficiente.&lt;/p&gt;

&lt;p&gt;Per approfondire l'analisi dei piani di esecuzione e comprendere meglio come SQL Server ottimizza le query, vi consiglio di dare un'occhiata al programma del mio &lt;strong&gt;&lt;a href="https://www.nicolaiantomasi.com/corso-sql-server/" rel="noopener noreferrer"&gt;corso su SQL Server&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Considerazioni Aggiuntive sull'Uso di LIKE
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Indici Full-Text:&lt;/strong&gt; Per ricerche complesse su grandi volumi di testo, considerare l'uso di indici full-text, che possono offrire prestazioni superiori rispetto a LIKE per pattern di ricerca complessi.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Escape di Caratteri Speciali:&lt;/strong&gt; Quando si cerca un carattere che è anche un carattere speciale in LIKE (come % o _), usare la clausola ESCAPE. Per esempio: 
&lt;code&gt;WHERE CodiceProdotto LIKE '%10\%%' ESCAPE '\'&lt;/code&gt; 
cerca codici che contengono esattamente "10%".&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;LIKE con Variabili:&lt;/strong&gt; Quando si usa LIKE con variabili, fare attenzione alla concatenazione di stringhe per evitare SQL injection. Preferire l'uso di parametri quando possibile.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;L'uso efficace di LIKE in combinazione con WHERE può significativamente migliorare la capacità di query e filtro dei dati in SQL Server. Tuttavia, è sempre importante bilanciare la flessibilità offerta da LIKE con le considerazioni sulle performance, specialmente quando si lavora con grandi volumi di dati.&lt;/p&gt;

</description>
      <category>sql</category>
      <category>sqlserver</category>
      <category>database</category>
    </item>
    <item>
      <title>Cosa sono e come gestire le transazioni su SQL Server</title>
      <dc:creator>Nicola Iantomasi</dc:creator>
      <pubDate>Tue, 07 Nov 2023 11:53:54 +0000</pubDate>
      <link>https://forem.com/nicola-iantomasi/cosa-sono-e-come-gestire-le-transazioni-su-sql-server-1d73</link>
      <guid>https://forem.com/nicola-iantomasi/cosa-sono-e-come-gestire-le-transazioni-su-sql-server-1d73</guid>
      <description>&lt;p&gt;Gestire correttamente gli errori durante l'esecuzione delle transazioni su SQL Server è vitale per mantenere l'integrità dei dati e assicurare il funzionamento corretto delle operazioni. &lt;/p&gt;

&lt;p&gt;Facciamo prima però un passo indietro e capiamo perché in alcuni casi è fondamentale usare le &lt;strong&gt;transazioni&lt;/strong&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  Le transazioni
&lt;/h2&gt;

&lt;p&gt;Per spiegare le transazioni prendiamo ad esempio il database di una banca in cui ogni giorno dobbiamo eseguire per migliaia di volte queste due operazioni: aggiungere una riga nella tabella dei movimenti dei conti correnti e aggiornare il valore della colonna saldo corrispondente. &lt;/p&gt;

&lt;p&gt;Cosa succederebbe se l'aggiunta del movimento andasse a buon fine, mentre l'aggiornamento del saldo per un qualsiasi motivo (anche per un banale &lt;em&gt;timeout&lt;/em&gt; o errore di rete) genera un errore?&lt;/p&gt;

&lt;p&gt;Sicuramente avremo molti clienti scontenti! In altri termini il nostro database si troverebbe in uno stato inconsistente e con importanti problemi di &lt;em&gt;Data Quality&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Un altro esempio: dobbiamo cancellare le righe da una tabella con una certa data di riferimento per inserirne subito dopo delle nuove con la medesima data.&lt;/p&gt;

&lt;p&gt;Cosa succede se, una volta confermata la cancellazione, l'inserimento dovesse fallire? Anche in questo caso avremmo una perdita dei dati, o comunque una situazione sicuramente meno consistente rispetto a quella di partenza.&lt;/p&gt;

&lt;p&gt;Questi sono solo alcuni esempi per cui risulta fondamentale avere sui Database un meccanismo per gestire le transazioni.&lt;/p&gt;

&lt;p&gt;L'obiettivo è eseguire alcuni specifici insiemi di operazioni di modifica dei dati in modo atomico, in modo da confermare tutti gli aggiornamenti contemporaneamente oppure annullarli se anche uno sola di essi non va a buon fine.&lt;/p&gt;

&lt;p&gt;Su un Database SQL Server, se lavoriamo con le impostazioni di Default, dobbiamo esplicitare l'operazione di apertura di una transazione con l'istruzione&lt;/p&gt;

&lt;p&gt;&lt;code&gt;BEGIN TRAN&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;per poi decidere di confermare o meno le modifiche tramite una Commit o una Rollback. Tuttavia il percorso non è sempre così lineare perché, come vedremo nel prossimo paragrafo, alcuni errori potrebbero chiudere automaticamente la transazione. Inoltre il nostro obiettivo è salvare il codice all'interno di &lt;strong&gt;procedure automatiche&lt;/strong&gt;, che riescano a gestire in autonomia il rollback in caso di errori, senza che qualcuno stia a lanciare l'istruzione manualmente.&lt;/p&gt;

&lt;h2&gt;
  
  
  Impatto degli errori sulle transazioni di SQL Server
&lt;/h2&gt;

&lt;p&gt;Su SQL Server un &lt;em&gt;errore di divisione per zero&lt;/em&gt; ha un impatto diverso sulla transazione rispetto a un &lt;em&gt;errore di conversione&lt;/em&gt;. Dopo aver avviato esplicitamente la transazione con BEGIN TRAN, un errore di divisione per zero lascia la transazione aperta, mentre un errore di conversione causa il &lt;strong&gt;rollback automatico&lt;/strong&gt; della transazione.&lt;/p&gt;

&lt;p&gt;Questo è solo un esempio, altri errori potrebbero provocare comportamenti diversi. Invece di enumerare tutti i casi possibili, studiamo come arricchire il nostro codice con il costrutto &lt;strong&gt;TRY-CATCH&lt;/strong&gt;, in modo da gestire in automatico la maggior parte dei possibili errori.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try Catch in SQL
&lt;/h2&gt;

&lt;p&gt;Il costrutto Try - Catch può essere usato in generale su SQL Server per gestire gli errori. Ad esempio l'istruzione&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;BEGIN TRY
   SELECT 1/0;
 END TRY
 BEGIN CATCH
   SELECT 2; 
 END CATCH
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;seleziona il valore 2. L'utilizzo di Try-Catch diventa davvero interessante se utilizzato per gestire in automatico gli errori durante una transazione. Analizziamo ad esempio questo codice:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;BEGIN TRY

 /* calcoli che non effettuano aggiornamenti dei dati */

 BEGIN TRAN

  DELETE FROM Tabella 
  WHERE DataRiferimento = @Datarif

  INSERT INTO Tabella (colonna1, colonna2)
  SELEC colonna1, colonna2 
  FROM  Staging_tabella

 COMMIT;
END TRY
BEGIN CATCH
 IF @@TRANCOUNT &amp;gt; 0 ROLLBACK;

 /* gestione errore */

 THROW;
END CATCH
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Prima di entrare nei dettagli del try-catch vi ricordo che specificare l'elenco delle colonne dopo una Insert come fatto in questo esempio rientra nelle &lt;a href="https://www.yimp.it/le-buone-abitudini-di-uno-sviluppatore-sql/"&gt;buone pratiche di uno sviluppatore SQL&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Analizziamo il codice precedente: la presenza del blocco &lt;em&gt;BEGIN TRY&lt;/em&gt; sposta immediatamente il flusso al blocco &lt;em&gt;CATCH&lt;/em&gt; in caso di errori. In questo modo la &lt;em&gt;Commit&lt;/em&gt;, essendo l'ultima istruzione del TRY, verrà eseguita solo quando sia la Delete e la Insert andranno a buon fine. Vi ricordo che è importante fare in modo che il codice dentro il blocco &lt;em&gt;BEGIN TRAN&lt;/em&gt; sia eseguito nel modo più veloce possibile per evitare l'insorgere di &lt;strong&gt;Deadlock&lt;/strong&gt;. A tal proposito ho dedicato un video sul mio canale Youtube &lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/md6z6myj1RM"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Tornando al nostro codice, nel blocco Catch viene eseguito subito un rollback nel caso ci sia qualche transazione aperta (l'IF serve perché l'errore si potrebbe generare anche nella parte di calcoli tra l'apertura del blocco Try e l'apertura del blocco Tran). Poi viene gestito l'errore, ad esempio andando a scrivere in una tabella di Log o inviando una mail, e infine possiamo (in base alla situazione) sollevare o meno nuovamente l'errore che ha portato il codice a passare nel blocco Catch.&lt;/p&gt;

&lt;p&gt;Concludiamo l'articolo menzionando che non tutti gli errori possono essere gestiti dal costrutto TRY-CATCH (come ad esempio alcuni errori di sintassi o timeout delle query quando lanciate da un client). In alcuni di questi casi potremmo prendere in considerazione l'utilizzo dell'istruzione &lt;a href="https://learn.microsoft.com/it-it/sql/t-sql/statements/set-xact-abort-transact-sql?view=sql-server-ver16"&gt;SET XACT_ABORT&lt;/a&gt;  &lt;/p&gt;

</description>
      <category>sql</category>
      <category>sqlserver</category>
      <category>transazioni</category>
      <category>trycatch</category>
    </item>
    <item>
      <title>Indici statistici: descrizione e implementazione in pandas</title>
      <dc:creator>Nicola Iantomasi</dc:creator>
      <pubDate>Wed, 01 Nov 2023 18:45:43 +0000</pubDate>
      <link>https://forem.com/nicola-iantomasi/indici-statistici-descrizione-e-implementazione-in-pandas-dn8</link>
      <guid>https://forem.com/nicola-iantomasi/indici-statistici-descrizione-e-implementazione-in-pandas-dn8</guid>
      <description>&lt;p&gt;Nel campo della statistica, gli indici sono valori numerici fondamentali che forniscono un riassunto efficiente di grandi quantità di dati. Questo articolo esplorerà due categorie chiave di indici, quelli univariati e multivariati, parlando anche della relativa implementazione con la libreria Pandas di Python.&lt;/p&gt;

&lt;h2&gt;
  
  
  Indici di statistica univariati con Pandas
&lt;/h2&gt;

&lt;p&gt;Gli indici univariati consentono un'analisi approfondita di una singola variabile all'interno di un insieme di dati. Partiamo allora creando un _DataFrame _con una sola colonna _Voti _&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import pandas as pd
Voti = pd.DataFrame(data=[25,23,28,25,24,29,25],columns = ["Voto"] )
Voti
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fokqz5ie3f1ane6xwkocs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fokqz5ie3f1ane6xwkocs.png" alt="dataframe d'esempio per calcolo degli indici statistici"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Tramite il metodo &lt;strong&gt;describe&lt;/strong&gt; otteniamo con una sola riga di codice il valore dei principali indici statistici di posizione e di variabilità. Facciamo attenzione però al valori di &lt;strong&gt;std&lt;/strong&gt; che corrisponde alla stima della deviazione standard della popolazione da cui è estratto il campione (al denominatore della formula ho n-1).&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Voti.describe()&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1klriaia1bbfkjyx4thr.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1klriaia1bbfkjyx4thr.jpg" alt="output del metodo describe di pandas"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Per calcolare gli &lt;strong&gt;indici di forma&lt;/strong&gt; possiamo creare prima una colonna con i valori standardizzati e poi applicare le formule degli indici di Fisher e di curtosi.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Voti["Voto_StandardScaler"] = (Voti["Voto"]-media)/deviazione_standard
AsimmetriaFisher = Voti["Voto_StandardScaler"].pow(3).mean()
Curtosi = Voti["Voto_StandardScaler"].pow(4).mean() - 3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Indici di statistica bivariati con Pandas
&lt;/h2&gt;

&lt;p&gt;Gli indici multivariati sono utilizzati per descrivere le relazioni tra due o più variabili in un insieme di dati. In base alla &lt;a href="https://www.yimp.it/scala-di-misura-variabile-statistica/" rel="noopener noreferrer"&gt;classificazione delle variabili statistiche&lt;/a&gt; è possibile calcolare l'associazione per tutte le combinazioni possibili:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;due variabili qualitative: si utilizzano comunemente &lt;strong&gt;l'indice Chi quadrato&lt;/strong&gt; e la sua versione normalizzata, la *&lt;em&gt;V di Cramer *&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;una variabile qualitativa e una quantitativa per i quale usiamo generalmente l'indice &lt;strong&gt;eta quadro&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;due variabili quantitative di cui il &lt;strong&gt;coefficiente di correlazione di Pearson&lt;/strong&gt; e &lt;strong&gt;quello di Spearman&lt;/strong&gt; sono due esempi &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Nel prossimo paragrafo ci concentreremo sugli indici relativi alle variabili qualitative&lt;/p&gt;

&lt;h2&gt;
  
  
  Indice Chi Quadrato e indice V di Cramer con Pandas
&lt;/h2&gt;

&lt;p&gt;Vediamo il codice per calcolare gli indici Chi Quadrato e V di Cramer con Pandas. Partiamo da un Dataframe con due colonne che contengono dati di tipo qualitativo, contenenti ad esempio il &lt;em&gt;colore degli occhi&lt;/em&gt; e &lt;em&gt;l'area geografica&lt;/em&gt;, di nome &lt;em&gt;DatiCramer&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Partiamo calcolando le frequenze osservate&lt;br&gt;
&lt;code&gt;FreqOsservate = DatiCramer.groupby(by = ["Occhi","Area geografica"],&lt;br&gt;
dropna = False,&lt;br&gt;
as_index = False).agg(conteggio = ("Occhi", np.size))&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Eseguiamo il pivot dei dati&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FreqOsservatePivot = FreqOsservate.pivot(columns = "Area geografica",
index = "Occhi", ).fillna(0)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Creiamo la tabella di contingenza con l'ausilio della libreria scipy&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import scipy.stats as stats
stats.chi2_contingency(FreqOsservatePivot, correction=False)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A questo punto possiamo calcolare l'indice chi-quadrato&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;indice_chi_quadrato = stats.chi2_contingency(FreqOsservatePivot,
correction=False)[0]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;e l'indice V di Cramer&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;n = len(DatiCramer)
k = len(DatiCramer["Occhi"].unique())
r = len(DatiCramer["Area geografica"].unique())
indice_v_cramer = pow(indice_chi_quadrato / (n*max(k-1,r-1)),0.5)
indice_v_cramer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Indice di correlazione di Pearson e di Spearman con Pandas
&lt;/h2&gt;

&lt;p&gt;Il calcolo degli indici di associazione tra due variabili quantitative è molto più immediato. Pandas infatti ci mette a disposizione il metodo &lt;strong&gt;corr&lt;/strong&gt; utilizzabile per calcolare le correlazioni tra tutte le coppie di variabili numeriche. Se non specifichiamo il parametro method, verrà calcolare l'indice di correlazione lineare di Pearson&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Dati.corr()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgd5o9pj49965s5npr9gy.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgd5o9pj49965s5npr9gy.jpg" alt="calcolo del coefficiente di Pearson tramite pandas"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Se invece volessi calcolare il coefficiente di Spearman, mi basterebbe scrivere&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Dati.corr(method="spearman")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>statistica</category>
      <category>python</category>
      <category>pandas</category>
    </item>
    <item>
      <title>Utilizzo di Python per la gestione dei dati: esplorazione delle librerie Pandas e Pymongo</title>
      <dc:creator>Nicola Iantomasi</dc:creator>
      <pubDate>Tue, 24 Oct 2023 07:05:37 +0000</pubDate>
      <link>https://forem.com/nicola-iantomasi/utilizzo-di-python-per-la-gestione-dei-dati-esplorazione-delle-librerie-pandas-e-pymongo-kpe</link>
      <guid>https://forem.com/nicola-iantomasi/utilizzo-di-python-per-la-gestione-dei-dati-esplorazione-delle-librerie-pandas-e-pymongo-kpe</guid>
      <description>&lt;p&gt;Python si è affermato come uno dei linguaggi di programmazione più popolari nel mondo, essendo particolarmente efficace nel settore della data science e del trattamento dei dati. Due delle sue librerie più utilizzate in questo ambito sono Pandas e Pymongo. In questo post vedremo qualche esempio d'uso di queste potenti librerie per importare e lavorare con dati da varie fonti.&lt;/p&gt;

&lt;h2&gt;
  
  
  Gestione dei dati CSV con Pandas
&lt;/h2&gt;

&lt;p&gt;Pandas è la libreria di Python per l'importazione e la manipolazione dei dati all'interno di un DataFrame. Un DataFrame è una struttura simile a una tabella con righe ordinate e nominate, chiamate indici del DataFrame.&lt;br&gt;
Il metodo read_csv è spesso usato per importare dati da un file csv. Esso permette di configurare diverse opzioni come il delimitatore, il qualificatore, la riga dell'intestazione, quelle da skippare, i formati delle date e dei numeri. Ecco un esempio di codice.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;import pandas as pd&lt;br&gt;
clienti = pd.read_csv(filepath_or_buffer = "Fatture.csv",&lt;br&gt;
                      sep = ";", &lt;br&gt;
                      header = 0,&lt;br&gt;
                      decimal=',')&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;In particolare abbiamo configurato:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;il nome del file "Fatture.csv";&lt;/li&gt;
&lt;li&gt;il carattere separatore (il punto e virgola ";");&lt;/li&gt;
&lt;li&gt;la posizione della riga di intestazione (0 corrisponde alla prima);&lt;/li&gt;
&lt;li&gt;il separatore delle cifre decimali (la virgola ",").&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In maniera simile, ci sono altri metodi per importare dati da altre fonti che organizzano i dati in tabelle, come Excel e i database SQL.&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/Q4xAuvhN7sI?start=7"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Gestione dei dati JSON con Pandas
&lt;/h2&gt;

&lt;p&gt;Il formato JSON è largamente usato come formato di interscambio. Pandas fornisce:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;il metodo read_json per importare direttamente dati da file in formato JSON&lt;/li&gt;
&lt;li&gt;il metodo json_normalize per creare un Dataframe a partire da una variabile di tipo dizionario. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Risulta importante osservare che a prescindere del formato iniziale (json, excel o csv) l'output sarà sempre un DataFrame. Questo è molto comodo per uniformare i dati importati in una struttura comune, che poi può essere lavorata in modo uniforme. Qui in particolare trovi degli &lt;a href="https://www.yimp.it/esercizi-python-con-soluzioni-pandas-e-analisi-dei-dati/"&gt;esercizi sull'analisi dei dati&lt;/a&gt;. D'altro lato però, potrebbe generare qualche difficoltà nella gestione delle chiavi JSON più complesse.&lt;/p&gt;

&lt;h2&gt;
  
  
  Gestione dei dati con Pymongo
&lt;/h2&gt;

&lt;p&gt;Pymongo è una libreria Python utilizzata per connettersi e interagire con i database NoSQL di MongoDb. Ecco il codice per connettersi ad un database locale installato a soli fini di test o esercizio personale.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;from pymongo import MongoClient&lt;br&gt;
client = MongoClient("mongodb://localhost:27017/")&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;In generale, è importante rispettare gli standard di sicurezza aziendali quando crei la connessione. Come minimo, dovresti evitare di scrivere direttamente nel codice l'username e la password.&lt;/p&gt;

&lt;p&gt;Dopo, puoi connetterti a un database MongoDb e usare le funzioni offerte da Pymongo per gestire i dati. Con questo codice, ad esempio, salvi nella variabile _result _le fatture con tipologia "A".&lt;/p&gt;

&lt;p&gt;&lt;code&gt;db = client.DatabaseMongoDB&lt;br&gt;
result = db.fatture.find({"tipologia":{$eq:"A"}});&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;La variabile _result _è un array di pymongo. Applicando il metodo _next _possiamo lavorare il contenuto del cursore "un documento alla volta"&lt;br&gt;
&lt;code&gt;document = result.next()&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;A questo punto posso utilizzare tutte le funzionalità dei dizionari di Python. Ad esempio con questo codice&lt;/p&gt;

&lt;p&gt;&lt;code&gt;document["id_fattura"]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;estraggo la chiave _id_fattura _del documento. &lt;/p&gt;

&lt;p&gt;Possiamo lavorare con i cursori anche tramite cicli for&lt;/p&gt;

&lt;p&gt;&lt;code&gt;for document in result:&lt;br&gt;
    print(document)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Oltre a leggere i dati, hai anche la possibilità di inserire, aggiornare o eliminare documenti dal database, ed eseguire query più complesse di aggregazione dei dati.&lt;/p&gt;

</description>
      <category>pandas</category>
      <category>pymongo</category>
      <category>python</category>
    </item>
    <item>
      <title>Linguaggio SQL e Join tra tabelle: una guida pratica all'uso</title>
      <dc:creator>Nicola Iantomasi</dc:creator>
      <pubDate>Mon, 16 Oct 2023 14:47:01 +0000</pubDate>
      <link>https://forem.com/nicola-iantomasi/linguaggio-sql-e-join-tra-tabelle-una-guida-pratica-alluso-4hln</link>
      <guid>https://forem.com/nicola-iantomasi/linguaggio-sql-e-join-tra-tabelle-una-guida-pratica-alluso-4hln</guid>
      <description>&lt;p&gt;Essere abili nella manipolazione dei dati con SQL è essenziale per qualsiasi Data Analyst. Uno degli strumenti più rilevanti in questo contesto sono le JOIN, che permettono di collegare i dati di diverse tabelle.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sintassi delle Join
&lt;/h2&gt;

&lt;p&gt;Per combinare i dati in più tabelle con il linguaggio SQL, dobbiamo scrivere una JOIN all'interno della clausola FROM e il comando ON per specificare la condizione secondo cui le righe devono essere unite. Ad esempio, per fondere le tabelle "post" e "comments" sulla colonna "post_id", si può utilizzare la seguente query:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;SELECT Fatture.*, Corrieri.NomeCorriere&lt;br&gt;
FROM Fatture&lt;br&gt;
INNER JOIN Corrieri&lt;br&gt;
ON Fatture.IdCorriere = Corrieri.IdCorriere;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Per ottenere un risultato che abbia senso nell'analisi dei dati, è importante assicurarsi che IdCorriere sia:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;una chiave primaria nella tabella Corrieri &lt;/li&gt;
&lt;li&gt;una chiave esterna nella tabella Fatture. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In caso contrario, si rischia di generare un output con dati duplicati o mancanti. &lt;/p&gt;
&lt;h2&gt;
  
  
  Scegliere la sintassi con JOIN esplicita
&lt;/h2&gt;

&lt;p&gt;Un aspetto importante che merita ulteriore enfasi è la scelta della sintassi con la JOIN esplicita, piuttosto che utilizzare una virgola nella FROM e aggiungere una condizione nella WHERE, come in questo esempio.&lt;/p&gt;

&lt;p&gt;Ci sono diversi motivi per cui questa opzione è preferibile:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;SELECT Fatture.*, Corrieri.NomeCorriere&lt;br&gt;
FROM Fatture, Corrieri&lt;br&gt;
WHERE Fatture.IdCorriere = Corrieri.IdCorriere;&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Leggibilità: La join separa la parte del codice che gestisce il collegamento tra le tabelle da quella che imposta altri filtri sui dati.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Facilità di modifica: Supponiamo che tu debba trasformare un'INNER JOIN in una LEFT JOIN. Se hai già esplicitato la JOIN, tutto ciò che devi fare è modificare una parola! Al contrario, su molti database, sarebbe necessario riscrivere completamente la query.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Aggiungo ulteriori dettagli &lt;a href="https://www.yimp.it/join-tra-tabelle-con-il-linguaggio-sql/#Perch%C3%A9-scegliere-la-sintassi-con-la-JOIN-esplicita"&gt;su questo paragrafo nel mio blog&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Rinominare colonne e tabelle nelle Join
&lt;/h2&gt;

&lt;p&gt;Per garantire la leggibilità delle query SQL, è buona norma usare nomi descrittivi e concisi per colonne e tabelle quando si utilizzano le JOIN. Questo facilita la lettura e permette di intervenire rapidamente se qualcosa nella nostra query non funziona come previsto. Ad esempio, potremmo riscrivere la query precedente in questo modo:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;SELECT f.*, c.NomeCorriere&lt;br&gt;
FROM Fatture as f&lt;br&gt;
LEFT JOIN Corrieri as c&lt;br&gt;
ON f.IdCorriere = c.IdCorriere;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Tipologie di join:&lt;br&gt;
Ci sono cinque tipi principali di JOIN, a seconda dell'obiettivo della query.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;INNER JOIN: unisce le tabelle utilizzando solo le righe che hanno corrispondenze in entrambe le tabelle.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;LEFT JOIN: oltre al risultato dell’INNER JOIN, include anche le righe della tabella di sinistra che non hanno corrispondenze.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;RIGHT JOIN: l'opposto del precedente, include al risultato dell’INNER JOIN anche le righe della tabella di destra che non hanno corrispondenze.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FULL JOIN: combina i risultati di LEFT e RIGHT, visualizzando sia le righe della tabella di sinistra che quelle di destra che non hanno corrispondenza.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CROSS JOIN: effettua tutte le combinazioni possibili, senza nessun criterio&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In questo video ragioniamo su quale tipologia di Join è meglio usare&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/c5xq1zo7tNk?start=6"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusione sull'utilizzo delle Join
&lt;/h2&gt;

&lt;p&gt;In conclusione, le JOIN sono uno strumento cruciale per la gestione dei dati in SQL. Tuttavia, è necessario fare attenzione a scegliere il tipo di Join appropriato in base al contesto e a formulare correttamente la condizione nell'ON.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Guida SQL: istruzione Where</title>
      <dc:creator>Nicola Iantomasi</dc:creator>
      <pubDate>Thu, 12 Oct 2023 07:48:47 +0000</pubDate>
      <link>https://forem.com/nicola-iantomasi/guida-sql-istruzione-where-5ffb</link>
      <guid>https://forem.com/nicola-iantomasi/guida-sql-istruzione-where-5ffb</guid>
      <description>&lt;p&gt;In SQL, filtrare i dati di una tabella è un'operazione molto importante per estrarre solo le informazioni di interesse. L'uso della parola chiave WHERE è il principale strumento per effettuare questa operazione. Cambiando le condizioni all'interno della clausola WHERE, è possibile selezionare righe specifiche della tabella in modo da ottenere solo le informazioni necessarie. &lt;/p&gt;

&lt;h2&gt;
  
  
  Operatori AND e OR nella Where SQL
&lt;/h2&gt;

&lt;p&gt;Per poter scrivere filtri complessi a piacere nella clausola WHERE, si possono utilizzare gli operatori AND e OR per combinare più condizioni tra di loro. Ad esempio, se volessimo selezionare solo le righe in cui la colonna "età" è maggiore o uguale a 25 e la colonna "provincia" è "Roma", possiamo utilizzare l'operatore AND:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT * 
FROM   tabella 
WHERE  eta &amp;gt;= 25 
   AND provincia = 'Roma';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Se invece avessimo voluto selezionare le righe in cui la colonna "provincia" fosse "Roma" o la colonna "provincia" fosse "Milano", avremmo utilizzato l'operatore OR:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT * 
FROM   tabella 
WHERE  provincia = 'Roma' 
    OR provincia = 'Milano';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Operatore IN:
&lt;/h2&gt;

&lt;p&gt;Un altro modo per filtrare più valori con una sola query è utilizzare l'operatore IN. Ad esempio, per selezionare le righe in cui la colonna "provincia" è "Roma", "Milano" o "Torino", possiamo utilizzare la seguente query, più veloce da scrivere rispetto all'OR: &lt;/p&gt;

&lt;p&gt;SELECT * &lt;br&gt;
FROM   tabella &lt;br&gt;
WHERE  provincia IN ('Roma', 'Milano', 'Torino');&lt;/p&gt;
&lt;h2&gt;
  
  
  Filtro sulle date
&lt;/h2&gt;

&lt;p&gt;Se vogliamo filtrare su colonne contenenti date, dobbiamo tenere conto della sintassi specifica del DBMS in uso. Ad esempio, utilizzando MySQL, per selezionare le righe in cui la colonna "data" è successiva al 2020-01-01, possiamo utilizzare la seguente query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT * 
FROM   tabella 
WHERE  data &amp;gt; '2020-01-01';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Valori NULL
&lt;/h2&gt;

&lt;p&gt;Infine, è importante tenere conto dei NULL. Per selezionare le righe in cui la colonna "provincia" è NULL, possiamo utilizzare 'IS NULL', ad esempio:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT * 
FROM   tabella 
WHERE  provincia IS NULL;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Al contrario, per selezionare le righe in cui la colonna "provincia" non è null, possiamo utilizzare 'IS NOT NULL':&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT * FROM tabella WHERE provincia IS NOT NULL;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusioni e approfondimenti
&lt;/h2&gt;

&lt;p&gt;In generale, filtrare i dati di una tabella tramite la clausola WHERE e gli altri operatori del linguaggio SQL è essenziale per estrarre solo le informazioni di interesse. Nel nostro esempio abbiamo visto come utilizzare gli operatori AND e OR, l'operatore IN, come filtrare le date e come gestire i valori NULL. Ricordate che ogni DBMS ha la sua sintassi specifica, quindi è importante consultare la documentazione ufficiale per gli esempi precisi.&lt;/p&gt;

&lt;p&gt;In questo articolo del mio blog parlo di come utilizzare la condizione &lt;a href="https://www.yimp.it/sql-server-filtro-campi-datetime/"&gt;WHERE su colonne di tipo Datetime di SQL Server&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Invece in questo video sul mio canale Youtube parlo di come scrivere le prima query con SQL e utilizzare l'istruzione WHERE&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/asUSFbJobqw?start=11"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
