Questo documento contiene query di esempio sulle voci di log archiviate in
bucket di log di cui è stato eseguito l'upgrade per l'utilizzo di Analisi dei log.
Su questi bucket puoi eseguire query SQL dalla pagina
Analisi dei log nella console Google Cloud. Per altri esempi, consulta
logging-analytics-samples
e
security-analytics
repository GitHub.
Questo documento non descrive SQL o come instradare e archiviare le voci di log. Per informazioni su questi argomenti, consulta la sezione Passaggi successivi.
Prima di iniziare
Per utilizzare le query mostrate in questo documento nella pagina Analisi dei log, sostituisci TABLE_NAME_OF_LOG_VIEW con il nome della tabella per la visualizzazione del log su cui vuoi eseguire la query. Questo nome ha il formato
project_ID.region.bucket_ID.view_ID
.Per identificare questo nome, vai all'elenco Visualizzazioni log nella pagina Analisi dei log, individua la visualizzazione log e seleziona Query. Il riquadro Query viene compilato con una query predefinita, che include il nome della tabella per la visualizzazione del log su cui viene eseguita la query. Per informazioni su come accedere alla query predefinita, consulta Eseguire query su una vista log.
Per utilizzare le query mostrate in questo documento nella pagina BigQuery Studio, sostituisci TABLE_NAME_OF_LOG_VIEW con il percorso alla tabella nel set di dati collegato. Ad esempio, per eseguire query sulla vista
_AllLogs
sul set di dati collegatomydataset
nel progettomyproject
, imposta questo campo sumyproject.mydataset._AllLogs
:Nella console Google Cloud, vai alla pagina BigQuery:
Puoi trovare questa pagina anche utilizzando la barra di ricerca.
Per aprire la pagina Analisi dei log:
-
Nella console Google Cloud, vai alla pagina Log Analytics:
Se utilizzi la barra di ricerca per trovare questa pagina, seleziona il risultato con il sottotitolo Logging.
(Facoltativo) Per identificare lo schema per la visualizzazione del log, Nell'elenco Viste log, trova la vista e poi seleziona nome della vista.
Viene visualizzato lo schema. Puoi utilizzare il campo Filtro per individuare campi specifici. Non puoi modificare lo schema.
-
Filtra log
Le query SQL determinano quali voci della visualizzazione del log elaborare, quindi raggruppano queste voci ed eseguono operazioni aggregate. Quando non sono elencate operazioni di raggruppamento e aggregazione, il risultato della query include le righe selezionate dall'operazione di filtro. Gli esempi in questa sezione illustrano il filtro.
Filtra per ora
Per impostare l'intervallo di tempo della query, ti consigliamo di utilizzare il selettore dell'intervallo di tempo. Questo selettore viene utilizzato automaticamente quando una query
non specifica un campo timestamp
nella clausola WHERE
.
Ad esempio, per visualizzare i dati relativi alla settimana precedente, seleziona Ultimi 7 giorni da
il selettore dell'intervallo di tempo. Puoi anche utilizzare il selettore dell'intervallo di ore per specificare un'ora di inizio e una di fine, un'ora di visualizzazione e cambiare i fusi orari.
Se includi un campo timestamp
nella clausola WHERE
, l'impostazione del selettore di intervallo di tempo non viene utilizzata. L'esempio seguente filtra i dati utilizzando la funzione TIMESTAMP_SUB
, che consente di specificare un intervallo di tempo dall'ora corrente:
WHERE
timestamp > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 1 HOUR)
Per ulteriori informazioni su come filtrare in base all'ora, consulta Funzioni di data e ora e Funzioni di timestamp.
Filtra per risorsa
Per filtrare in base alla risorsa, aggiungi una limitazione resource.type
.
Ad esempio, la seguente query legge l'ora di dati più recente, poi conserva le righe il cui tipo di risorsa corrisponde a gce_instance
, quindi ordina e mostra fino a 100 voci:
SELECT
timestamp, log_name, severity, json_payload, resource, labels
FROM
`TABLE_NAME_OF_LOG_VIEW`
WHERE
resource.type = "gce_instance"
ORDER BY timestamp ASC
LIMIT 100
Filtra per gravità
Puoi filtrare in base a una gravità specifica con una restrizione come
severity = 'ERROR'
. Un'altra opzione è utilizzare l'istruzione IN
e specificare un insieme di valori validi.
Ad esempio, la seguente query legge l'ora di dati più recente e
e conserva solo le righe che contengono un campo severity
il cui valore è
'INFO'
o 'ERROR'
:
SELECT
timestamp, log_name, severity, json_payload, resource, labels
FROM
`TABLE_NAME_OF_LOG_VIEW`
WHERE
severity IS NOT NULL AND
severity IN ('INFO', 'ERROR')
ORDER BY timestamp ASC
LIMIT 100
La query precedente filtra in base al valore del campo severity
. Tuttavia,
puoi anche scrivere query che filtrano in base al valore numerico della gravità del log.
Ad esempio, se sostituisci le righe severity
con le seguenti,
la query restituisce tutte le voci di log con un livello di gravità minimo pari a NOTICE
:
severity_number IS NOT NULL AND
severity_number > 200
Per informazioni sui valori enumerati, consulta
LogSeverity
.
Filtra per nome del log
Per filtrare in base al nome di log, puoi aggiungere una restrizione al valore della variabile
log_name
o il campo log_id
. Il campo log_name
include la risorsa
del tuo percorso di apprendimento. In altre parole, questo campo ha valori come projects/myproject/logs/mylog
.
Il campo log_id
memorizza solo il nome del log, ad esempio mylog
.
Ad esempio, la seguente query legge l'ora di dati più recente, quindi conserva le righe in cui il valore nel campo log_id
è cloudaudit.googleapis.com/data_access
, quindi ordina e mostra i risultati:
SELECT
timestamp, log_id, severity, json_payload, resource, labels
FROM
`TABLE_NAME_OF_LOG_VIEW`
WHERE
log_id = "cloudaudit.googleapis.com/data_access"
ORDER BY timestamp ASC
LIMIT 100
Filtra per etichetta della risorsa
La maggior parte dei descrittori risorsa monitorata definisce le etichette utilizzate per identificare risorsa specifica. Ad esempio, il descrittore per un'istanza Compute Engine include le etichette per la zona, l'ID progetto e l'ID istanza. Quando viene scritta la voce del log, i valori vengono assegnati a ciascun campo. Di seguito è riportato un esempio di questo tipo:
{
type: "gce_instance"
labels: {
instance_id: "1234512345123451"
project_id: "my-project"
zone: "us-central1-f"
}
}
Poiché il tipo di dati del campo labels
è JSON, l'inclusione di una limitazione come resource.labels.zone = "us-centra1-f"
in una query genera un errore di sintassi. Per ottenere il valore di un campo con un tipo di dati JSON, utilizza la funzione
JSON_VALUE
Ad esempio, la seguente query legge i dati più recenti e poi conserva quelle righe in cui la risorsa è un'istanza Compute Engine situata nella zona us-central1-f
:
SELECT
timestamp, log_name, severity, JSON_VALUE(resource.labels.zone) AS zone, json_payload, resource, labels
FROM
`TABLE_NAME_OF_LOG_VIEW`
WHERE
resource.type = "gce_instance" AND
JSON_VALUE(resource.labels.zone) = "us-central1-f"
ORDER BY timestamp ASC
LIMIT 100
Per informazioni su tutte le funzioni che possono recuperare e trasformare JSON vedi Funzioni JSON.
Filtra per richiesta HTTP
Per filtrare la visualizzazione log in modo da includere solo le voci di log corrispondenti a una richiesta o una risposta HTTP, aggiungi una limitazione http_request IS NOT NULL
:
SELECT
timestamp, log_name, severity, http_request, resource, labels
FROM
`TABLE_NAME_OF_LOG_VIEW`
WHERE
http_request IS NOT NULL
ORDER BY timestamp
LIMIT 100
La seguente query include solo le righe che corrispondono a GET
o POST
richieste:
SELECT
timestamp, log_name, severity, http_request, resource, labels
FROM
`TABLE_NAME_OF_LOG_VIEW`
WHERE
http_request IS NOT NULL AND
http_request.request_method IN ('GET', 'POST')
ORDER BY timestamp ASC
LIMIT 100
Filtra per stato HTTP
Per filtrare in base allo stato HTTP, modifica la clausola WHERE
in modo che richieda il
http_request.status
campo da definire:
SELECT
timestamp, log_name, http_request.status, http_request, resource, labels
FROM
`TABLE_NAME_OF_LOG_VIEW`
WHERE
http_request IS NOT NULL AND
http_request.status IS NOT NULL
ORDER BY timestamp ASC
LIMIT 100
Per determinare il tipo di dati archiviati in un campo, visualizza lo schema o mostra
campo. I risultati della query precedente mostrano che il
http_request.status
campo memorizza valori interi.
Filtra per un campo con un tipo JSON
Per estrarre un valore da una colonna il cui tipo di dati è JSON, utilizza la funzione
JSON_VALUE
.
Considera le seguenti query:
SELECT
json_payload
FROM
`TABLE_NAME_OF_LOG_VIEW`
WHERE
json_payload.status IS NOT NULL
e
SELECT
json_payload
FROM
`TABLE_NAME_OF_LOG_VIEW`
WHERE
JSON_VALUE(json_payload.status) IS NOT NULL
Le query precedenti verificano il valore del campo json_payload
nella
voce di log. Entrambe le query
ignora le voci di log che non contengono un campo con l'etichetta json_payload
.
La differenza tra queste due query è la riga finale, che definisce
gli elementi rispetto ai quali viene eseguito il test NULL
. Consideriamo ora una visualizzazione log che
due voci di log. Per una voce di log, il campo json_payload
ha il seguente
formato:
{
status: {
measureTime: "1661517845"
}
}
Per l'altra voce di log, il campo json_payload
ha una struttura diversa:
{
@type: "type.googleapis.com/google.cloud.scheduler.logging.AttemptFinished"
jobName: "projects/my-project/locations/us-central1/jobs/test1"
relativeUrl: "/food=cake"
status: "NOT_FOUND"
targetType: "APP_ENGINE_HTTP"
}
Entrambe le voci di log precedenti soddisfano la limitazionejson_payload.status IS NOT NULL
.
Ciò significa che il risultato della prima query include entrambe le voci di log.
Tuttavia, quando la limitazione è JSON_VALUE(json_payload.status) IS NOT NULL
,
solo la seconda voce di log è inclusa nel risultato della query.
Filtra per espressione regolare
Per restituire la sottostringa che corrisponde a un'espressione regolare, utilizza la funzione
REGEXP_EXTRACT
. Il tipo di ritorno di questa funzione è
STRING
o BYTES
.
La seguente query mostra le voci di log ricevute più di recente, conserva
queste voci con un campo json_payload.jobName
, quindi visualizza
parte del nome che inizia con test
:
SELECT
timestamp, REGEXP_EXTRACT(JSON_VALUE(json_payload.jobName), r".*(test.*)$") AS name,
FROM
`TABLE_NAME_OF_LOG_VIEW`
WHERE
json_payload.jobName IS NOT NULL
ORDER BY timestamp DESC
LIMIT 20
Per ulteriori esempi, consulta
Documentazione di REGEXP_EXTRACT
.
Per esempi di altre espressioni regolari che
che puoi utilizzare, consulta Funzioni, operatori e condizionali.
La query mostrata in questo esempio non è efficace. Per una corrispondenza di sottostringa, come quella illustrata, utilizza la funzione CONTAINS_SUBSTR
.
Raggruppa e aggrega le voci di log
Questa sezione si basa sugli esempi precedenti e illustra come puoi
raggruppa e aggrega le voci di log. Se non specifichi un raggruppamento, ma specifichi un'aggregazione, viene stampato un singolo risultato perché SQL tratta tutte le righe che soddisfano la clausola WHERE
come un unico gruppo.
Ogni espressione SELECT
deve essere inclusa nei campi del gruppo o essere aggregata.
Raggruppa per ora
Per raggruppare i dati in base all'ora, utilizza la funzione TIMESTAMP_TRUNC
,
che tronca un timestamp a una granularità specificata come MINUTE
. Per
ad esempio un timestamp di 15:30:11
, formattato come
hours:minutes:seconds
, diventa 15:30:00
quando la granularità è impostata su
MINUTE
.
La seguente query legge i dati ricevuti nell'intervallo specificato
il selettore dell'intervallo di tempo e poi conserva
le righe in cui il valore del campo json_payload.status
non è NULL.
La query tronca il timestamp di ogni riga per ora e poi raggruppa le righe in base al timestamp e allo stato troncati:
SELECT
TIMESTAMP_TRUNC(timestamp, HOUR) AS hour,
JSON_VALUE(json_payload.status) AS status,
COUNT(*) AS count
FROM
`TABLE_NAME_OF_LOG_VIEW`
WHERE
json_payload IS NOT NULL AND
JSON_VALUE(json_payload.status) IS NOT NULL
GROUP BY hour,status
ORDER BY hour ASC
Per altri esempi, consulta la documentazione di TIMESTAMP_TRUNC
.
Per informazioni sulle altre funzioni basate sul tempo, vedi
Funzioni data/ora:
Raggruppa per risorsa
La seguente query legge l'ora di dati più recente e raggruppa le voci di log per tipo di risorsa. Quindi conteggia il numero di righe per ogni risorsa e restituisce una tabella con due colonne. La prima colonna elenca il tipo di risorsa, mentre la seconda colonna indica il numero di righe per quel tipo di risorsa:
SELECT
resource.type, COUNT(*) AS count
FROM
`TABLE_NAME_OF_LOG_VIEW`
GROUP BY resource.type
LIMIT 100
Raggruppa per gravità
La seguente query legge l'ora più recente dei dati e poi conserva le righe con un campo di gravità. La query raggruppa quindi le righe in base alla gravità e conteggia il numero di righe per ogni gruppo:
SELECT
severity, COUNT(*) AS count
FROM
`TABLE_NAME_OF_LOG_VIEW`
WHERE
severity IS NOT NULL
GROUP BY severity
ORDER BY severity
LIMIT 100
Raggruppa per log_id
Il risultato della seguente query è una tabella con due colonne. Il primo colonna elenca i nomi log e la seconda colonna elenca il numero scritte nel log. La query ordina i risultati in base al numero di voci:
SELECT
log_id, COUNT(*) AS count
FROM
`TABLE_NAME_OF_LOG_VIEW`
GROUP BY log_id
ORDER BY count DESC
LIMIT 100
Calcolo della latenza media per la richiesta HTTP
La query seguente illustra il raggruppamento per più colonne e il calcolo di un valore medio. La query raggruppa le righe in base all'URL contenuto nella richiesta HTTP e al valore del campo labels.checker_location
. Dopo aver raggruppato le righe, la query calcola la latenza media per ogni gruppo:
SELECT
JSON_VALUE(labels.checker_location) AS location,
AVG(http_request.latency.seconds) AS secs, http_request.request_url
FROM
`TABLE_NAME_OF_LOG_VIEW`
WHERE
http_request IS NOT NULL AND
http_request.request_method IN ('GET')
GROUP BY http_request.request_url, location
ORDER BY location
LIMIT 100
Nell'espressione precedente, JSON_VALUE
è necessario per estrarre il valore
del campo labels.checker_location
perché il tipo di dati
labels
è un file JSON.
Tuttavia, non utilizzi questa funzione per estrarre il valore dal
campo http_request.latency.seconds
. Quest'ultimo campo ha un tipo di dati
numero intero.
Media di byte di calcolo inviati per un test della subnet
La seguente query illustra come potresti visualizzare il numero medio di byte inviati per località.
La query legge l'ora più recente dei dati e conserva solo le righe
la cui colonna del tipo di risorsa è gce_subnetwork
e la cui colonna json_payload
non è NULL. Successivamente, la query raggruppa le righe in base alla posizione
risorsa. A differenza dell'esempio precedente, in cui i dati sono archiviati come numeri
, il valore del campo bytes_sent
è una stringa e pertanto devi
converti il valore in FLOAT64
prima di calcolare la media:
SELECT JSON_VALUE(resource.labels.location) AS location,
AVG(CAST(JSON_VALUE(json_payload.bytes_sent) AS FLOAT64)) AS bytes
FROM
`TABLE_NAME_OF_LOG_VIEW`
WHERE
resource.type = "gce_subnetwork" AND
json_payload IS NOT NULL
GROUP BY location
LIMIT 100
Il risultato della query precedente è una tabella in cui ogni riga elenca una località e i byte inviati in media per quella località.
Per informazioni su tutte le funzioni che possono recuperare e trasformare i dati JSON, consulta Funzioni JSON.
Per informazioni su CAST
e su altre funzioni di conversione, consulta
Funzioni di conversione.
Conta le voci di log con un campo corrispondente a un pattern
Per restituire la sottostringa che corrisponde a un'espressione regolare, utilizza la funzione
REGEXP_EXTRACT
. Il tipo restituito di questa funzione è
STRING
o BYTES
.
La seguente query conserva le voci di log per le quali il valore
del campo json_payload.jobName
non è NULL.
Poi raggruppa le voci in base al suffisso del nome che inizia
con test
. Infine, la query conteggia il numero di voci in ogni gruppo:
SELECT
REGEXP_EXTRACT(JSON_VALUE(json_payload.jobName), r".*(test.*)$") AS name,
COUNT(*) AS count
FROM
`TABLE_NAME_OF_LOG_VIEW`
WHERE
json_payload.jobName IS NOT NULL
GROUP BY name
ORDER BY count
LIMIT 20
Per altri esempi, consulta la documentazione di REGEXP_EXTRACT
.
Per esempi di altre espressioni regolari che
che puoi utilizzare, consulta Funzioni, operatori e condizionali.
Ricerca tra colonne
Questa sezione descrive due approcci diversi che puoi utilizzare per eseguire ricerche in più colonne di una tabella.
Ricerca basata su token
Per cercare in una visualizzazione del log le voci corrispondenti a un insieme di termini di ricerca,
usa la funzione SEARCH
. Questa funzione richiede due parametri:
dove effettuare la ricerca e la query di ricerca.
Poiché la funzione SEARCH
ha regole specifiche su come vengono cercati i dati,
consigliamo di leggere la documentazione di SEARCH
.
La seguente query conserva solo le righe con un campo corrispondente esattamente a "35.193.12.15":
SELECT
timestamp, log_id, proto_payload, severity, resource.type, resource, labels
FROM
`TABLE_NAME_OF_LOG_VIEW` AS t
WHERE
proto_payload IS NOT NULL AND
log_id = "cloudaudit.googleapis.com/data_access" AND
SEARCH(t,"`35.193.12.15`")
ORDER BY timestamp ASC
LIMIT 20
Nella query precedente, le barre graffe racchiudono il valore da cercare. Questo
Garantisce che la funzione SEARCH
cerchi una corrispondenza esatta tra
il valore del campo e il valore tra gli accenti inversi.
Quando gli apici inversi vengono omessi nella stringa di query, quest'ultima viene divisa
in base alle regole definite nella documentazione di SEARCH
.
Ad esempio, quando viene eseguito il seguente statement,
la stringa di query viene suddivisa in quattro token: "35", "193", "12" e "15":
SEARCH(t,"35.193.12.15")
L'istruzione SEARCH
precedente corrisponde a una riga quando un singolo campo corrisponde a tutti e quattro i token. L'ordine dei token non è importante.
Puoi includere più istruzioni SEARCH
in una query. Ad esempio, nel
una query precedente, potresti sostituire il filtro sull'ID log con una
come la seguente:
SEARCH(t,"`cloudaudit.googleapis.com/data_access`")
L'istruzione precedente cerca in ogni campo delle voci di log nella visualizzazione dei log, mentre l'istruzione originale cerca solo nel campo log_id
delle voci di log.
Per eseguire più ricerche in più campi, separa le singole stringhe con uno spazio. Ad esempio, l'istruzione seguente corrisponde alle righe in cui un campo contiene "Hello World", "happy" e "days":
SEARCH(t,"`Hello World` happy days")
Infine, puoi cercare in campi specifici anziché in un'intera tabella. Ad esempio, la seguente istruzione cerca solo
le colonne denominate text_payload
e json_payload
:
SEARCH((text_payload, json_payload) ,"`35.222.132.245`")
Per informazioni su come vengono elaborati i parametri della funzione SEARCH
,
consulta la pagina di riferimento di BigQuery Funzioni di ricerca.
Ricerca di sottostringhe
Per eseguire un test senza distinzione tra maiuscole e minuscole per determinare se un valore esiste in un'espressione, utilizza la funzione CONTAINS_SUBSTR
.
Questa funzione restituisce TRUE
se il valore esiste e
FALSE
in caso contrario. Il valore di ricerca deve essere un valore letterale STRING
, ma non il valore letterale NULL
.
Ad esempio, la seguente query recupera tutte le voci del log di controllo di accesso ai dati con un indirizzo IP specifico i cui timestamp sono compresi in un determinato intervallo di tempo. Infine, la query ordina i risultati e mostra i 20 risultati meno recenti:
SELECT
timestamp, log_id, proto_payload, severity, resource.type, resource, labels
FROM
`TABLE_NAME_OF_LOG_VIEW` AS t
WHERE
proto_payload IS NOT NULL AND
log_id = "cloudaudit.googleapis.com/data_access" AND
CONTAINS_SUBSTR(t,"35.193.12.15")
ORDER BY timestamp ASC
LIMIT 20
La query precedente esegue un test delle sottostringhe. Pertanto, una riga che contiene
"35.193.12.152" corrisponde all'istruzione CONTAINS_SUBSTR
.
Combinare dati da più origini
Le istruzioni di query analizzano una o più tabelle o espressioni e restituiscono il valore
e le righe di risultati calcolate. Ad esempio, puoi utilizzare le istruzioni per le query per unire
risultati di istruzioni SELECT
su tabelle o set di dati diversi in un
in vari modi e poi selezionare le colonne dai dati combinati.
Combinare i dati di due tabelle con le unioni
Per combinare le informazioni di due tabelle, utilizza l'opzione join . Il tipo di join e la clausola condizionale utilizzata determinano come vengono combinate ed eliminate le righe.
La seguente query fornisce i campi json_payload
dalle righe di due tabelle diverse scritte dallo stesso intervallo di traccia. La query esegue
inner JOIN
su due tabelle per le righe in cui i valori di
le colonne span_id
e trace
in entrambe le tabelle corrispondono. Da questo risultato,
la query seleziona quindi i campi timestamp
, severity
e json_payload
proveniente da TABLE_NAME_OF_LOG_VIEW_1, il campo json_payload
di
ABLE_NAME_OF_LOG_VIEW_2 e i valori di span_id
e trace
campi su cui sono state unite le due tabelle e restituisce fino a 100
righe:
SELECT
a.timestamp, a.severity, a.json_payload, b.json_payload, a.span_id, a.trace
FROM `TABLE_NAME_OF_LOG_VIEW_1` a
JOIN `ABLE_NAME_OF_LOG_VIEW_2` b
ON
a.span_id = b.span_id AND
a.trace = b.trace
LIMIT 100
Combina più selezioni con le unioni
Per combinare i risultati di due o più istruzioni SELECT
e ignorare
righe duplicate, utilizza l'operatore UNION
. Per conservare i duplicati
di righe, utilizza l'operatore UNION ALL
.
La seguente query legge l'ora più recente di dati da TABLE_NAME_OF_LOG_VIEW_1, unisce il risultato con l'ora più recente di dati da ABLE_NAME_OF_LOG_VIEW_2, ordina i dati uniti in base al timestamp crescente e poi mostra le 100 voci più vecchie:
SELECT
timestamp, log_name, severity, json_payload, resource, labels
FROM(
SELECT * FROM `TABLE_NAME_OF_LOG_VIEW_1`
UNION ALL
SELECT * FROM `ABLE_NAME_OF_LOG_VIEW_2`
)
ORDER BY timestamp ASC
LIMIT 100
Limitazioni
Le query utilizzate nella pagina Analisi dei log supportano le funzioni GoogleSQL con alcune eccezioni.
I seguenti comandi SQL non sono supportati per le query SQL eseguite utilizzando il comando Pagina Analisi dei log:
- Comandi DDL e DML
- Funzioni definite dall'utente di JavaScript
- Funzioni di BigQuery ML
- Variabili SQL
I seguenti elementi sono supportati solo quando esegui query su un set di dati collegato utilizzando le pagine BigQuery Studio e Looker Studio e lo strumento a riga di comando bq:
- Funzioni definite dall'utente di JavaScript
- Funzioni di BigQuery ML
- Variabili SQL
Passaggi successivi
Per informazioni su come indirizzare e archiviare le voci di log, consulta i seguenti documenti:
- Crea un bucket di log
- Eseguire l'upgrade di un bucket per utilizzare Analisi dei log
- Collegare un bucket di log a un set di dati BigQuery
- Configura e gestisci i sink
Per la documentazione di riferimento su SQL, consulta i seguenti documenti: