Comando WITH....AS()

di il
5 risposte

Comando WITH....AS()

Buongiorno,

Sono nuovo del forum. Sto cercando di imparare il linguaggio SQL in autodidatta ma non mi risulta facile da comprendere...

Sto seguendo dei corsi di Google per il Google Cloud Computing dove dichiarano non sia necessari alcuna particolre skill per seguire questi corsi......

Invece mi vedo obbligato a studiare il linguaggio SQL.

Potete gentilmente aiutarmi? Di seguito l'istruzione. dovrebbe essere corretta ho trovato la soluzione online ma proprio non la capisco. il comando "with" prima del select??? che è a che serve?? il resto del linguaggio ok lo capisco ma mi risulta difficile formulare una query simile data una specifica istruzione (passare da query in real a query in linguaggio SQL).



with deaths_by_states as (
SELECT subregion1_name as state, sum(cumulative_deceased) as death_count
FROM `bigquery-public-data.covid19_open_data.covid19_open_data`
where country_name="United States of America" and date='2020-04-10' and subregion1_name is NOT NULL
group by subregion1_name
)

select count(*) as count_of_states
from deaths_by_states
where death_count > 100



Vi prego di aiutarmi se avete anche qualche suggeimento libro o altro dove posso studiare l'SQL adatto alle mie esigenze (Data Analyst), deduco che sia solo interrogazione dei dati già archiviati nel database e non manipolazione o altro...

5 Risposte

  • Re: Comando WITH....AS()

    Guarda i commenti aggiunti al tuo codice

    pergo91 ha scritto:



    --- questa puoi immaginarla come fosse una vista
    with deaths_by_states as (
    SELECT subregion1_name as state, sum(cumulative_deceased) as death_count
    FROM `bigquery-public-data.covid19_open_data.covid19_open_data`
    where country_name="United States of America" and date='2020-04-10' and subregion1_name is NOT NULL
    group by subregion1_name
    )
    --- qui fai la select dalla vista precedente
    select count(*) as count_of_states
    from deaths_by_states
    where death_count > 100
  • Re: Comando WITH....AS()

    Salve e benvenuto,
    ti rispondo in pubblico e non in privato in quanto i forum nascono proprio per avere discussioni pubbliche alle quali tutti possono dare il proprio contributo.

    l'acronimo SQL sta per Structured Query Language, ed e' un linguaggio definito con standard ISO al quale i vari produttori tendono (man mano) ad uniformarsi, pur mantenendosi la liberta' di definire un proprio "dialetto". Questo particolare forum e' dedicato a Microsoft SQL Server, ma sempre qui trovi apposite sezioni per MySQL, Oracle, ...., ed ognuno di essi ha un proprio dialetto particolare, nel caso di SQL Server, il dialetto e' Transact-SQL (T-SQL), derivante dall'originaria Sybase dalla quale Microsoft ha originato il proprio database engine.

    relativamente alla clausola "WITH xxx AS ( ....", questa e' definita come una Common Table Expression, e nella sua forma principale (non ricorsiva) tendenzialmente definisce una "sub-query"
    https://docs.microsoft.com/it-it/sql/t-sql/queries/with-common-table-expression-transact-sql?view=sql-server-ver15,
    da utilizzarsi successivamente alla sua definizione nel corpo di un comando DML (SELECT | UPDATE | INSERT | DELETE)...

    trivialmente, invece di definire un comando che ad esempio proietti 1 resultset con o senza relazioni ad altri result set tipo
    
    SELECT x, y, z
        FROM t1
        JOIN (
            -- sub query innestata
            SELECT x, y, z
                FROM t2
                WHERE ...) AS t2 ON t2.x = t1.x
        WHERE ....
        ORDER BY ....;
    
    dove all'oggetto t1 viene relazionato con una sub-query innestata in-line, il cui result set intermedio viene referenziato come t2, quindi nidificando una proiezione intermedia (sub-query) all'interno di una proiezione "globale".

    vista la "difficile" leggibilita' di tale tipo di codice, e' stata implementa a livello ISO la clausola di definizione delle Common Table Expressions, che permette di "spostare al di fuori" del comando "principale" la proiezione di result set intermedi, permettendo quindi una maggiore leggibilita', diventando quindi, sempre ad esempio:
    
    WITH cte AS (
      SELECT x, y, z
                  FROM t2
                  WHERE ...
        )
    SELECT x, y, z
        FROM t1
        JOIN cte ON cte.x = t1.x
        WHERE ....
        ORDER BY ....;
    
    in termini prestazionali il risultato e' indifferente, ma il codice guadagna di semplicita' di lettura.

    non e' necessario che sia presente una relazione tra oggetti diversi nel comando generato, quindi la CTE puo' anche facilmente tradursi in
    
    WITH cte AS (
      SELECT x, y, z
                  FROM t2
                  WHERE ...
        )
    SELECT x, y, z
        FROM cte
        ORDER BY ....;
    
    anche se questo e' poco comune in quanto superfluo, ma spesso viene anche usato per effettuare ad esempio raggruppamenti/calcoli precedenti alla effettiva proiezione finale tipo
    
    WITH cte AS (
      SELECT x, MAX(y) AS [maxY]
                  FROM t2
                  WHERE ...
        )
    SELECT x, [maxY]
        FROM cte
        WHERE ...
        ORDER BY ....;
    
    come anche per funzionalita' di paginazione "semplicistica" tipo
    
    -- paginazione dei dati, in questo caso recupero delle righe "posizionate" da 20 a 30
    ->param @init int = 20;
    ->param @end int = 30;
     
    WITH cte_customers AS (
        SELECT 
            ROW_NUMBER() OVER( ORDER BY 
                                first_name, 
                                last_name
                            ) row_num, 
            customer_id, 
            first_name, 
            last_name
            FROM 
                sales.customers
        ) 
        SELECT 
          customer_id, 
          first_name, 
          last_name
          FROM cte_customers
            WHERE 
              row_num > @init AND 
              row_num <= @end;
    
    o altro, anche se, per questo esempio specifico, ci sono ovviamente tecniche migliori di paginazione, vedi ad esempio https://sqlperformance.com/2015/01/t-sql-queries/pagination-with-offset-fetch


    nel caso specifco che riporti,
    
    with deaths_by_states as (
        SELECT subregion1_name as state, sum(cumulative_deceased) as death_count
            FROM `bigquery-public-data.covid19_open_data.covid19_open_data`
            where country_name="United States of America" 
                and date='2020-04-10' 
                and subregion1_name is NOT NULL
        group by subregion1_name
    )
    select count(*) as count_of_states
        from deaths_by_states
        where death_count > 100
    
    come dicevo poc'anzi, viene prima utilizzata la "sub-query" definita dalla Common Table Expression per recuperare un resultset temporaneo che:
    - raggruppando per subregion1_name
    - ottenga il valore di subregion1_name e la somma dei decessi
    - filtrando la proiezione per
    country_name="United States of America"
    nel giorno date='2020-04-10'

    questo set temporaneo viene poi filtrato per
    - death_count > 100
    e quindi proietta il numero delle righe risultanti

    Vi prego di aiutarmi se avete anche qualche suggeimento libro o altro dove posso studiare l'SQL adatto alle mie esigenze (Data Analyst), deduco che sia solo interrogazione dei dati già archiviati nel database e non manipolazione o altro...
    comprendo la necessita' "restringere" il campo di studio, ma per certi versi sarebbe come insegnare a guidare un veicolo andando sempre e solo in 1° marcia... bisogna sapere che ci sono anche altre marce

    sinceramente non saprei indicarti un "libro" standard in questo senso... personalmente per i linguaggi ho sempre preso pubblicazioni dedicate al RDBMS specifico...
    devi studiare SQL Server?

    salutoni romagnoli
    --
    Andrea
  • Re: Comando WITH....AS()

    Mamma mia Andrea grazie della spiegazione!!

    Si sto seguendo questi corsi di Google Cloud
    https://google.qwiklabs.com/quests/12
    https://google.qwiklabs.com/quests/13
    https://google.qwiklabs.com/quests/11

    Ci sono alcuni argomenti che vanno ad toccare comandi in Javascript , API e altro per sviluppatori di software, io non ci capisco un H di sta roba.
    Ho fatto apposta qualche corso base di Javascript ma serve un livello un po più avanzato

    Mi sto preparando per il test di uno dei tre moduli che ti ho linkato, e richiede una certa preparazione in SQL che piano piano sto imparando ma un po così a "tozzi e bocconi" sto andando lentissimo, visto che nel mentre provo a testare le mie capacità per vedere se ho capito veramente quello che sto studiando o se appena esco dalla "comfort zone" faccio danni....
    beh 1/3 mi inceppo e ristudio da capo e approfondisco.

    Quindi laddove una buon anima con una discreta conoscenza di SQL ci mette un ora a fare sto modulo io ci metto 1 mese

    L'informatica non è il mio campo, lavoro nel commerciale vendite e marketing, per questo vorrei studiare per diventare "Data Analyst" così da poter interrogare i database di GCP in autonomia ed avere quel miglio in più per poter capire questo mondo "alieno" che è l'IT con i suoi database e simili...
  • Re: Comando WITH....AS()

    Salve a tutti,
    @sspintux e' stato altrettanto chiaro... concisissimo ma chiaro...
    c'e' chi riesce ad avere il dono della sintesi :D

    salutoni romagnoli ed in bocca al lupo a @pergo91
    --
    Andrea
  • Re: Comando WITH....AS()

    Bhe... diciamo che c'è sia il libro completo che il Bignami del Bignami

Devi accedere o registrarti per scrivere nel forum
5 risposte