In questa lezione imparerai come codificare le istruzioni SELECT che recuperano i dati da un unica tabella. Dovresti capire, tuttavia, che le competenze trattate qui sono quelle essenziali che si applicano a qualsiasi istruzione SELECT che codifichi... non importa su quante tabelle opera, indipendentemente dalla complessità del recupero. Quindi vi deve essere una buona comprensione del materiale contenuto in questa lezione prima di passare alle lezioni successive.
Per aiutarti a imparare a codificare le istruzioni SELECT, questa lezione inizia presentando la sintassi di base. Successivamente, presenta diversi esempi che ti daranno un'idea di cosa puoi fare con questa istruzione. Il resto di questa lezione ti insegnerà i dettagli su come codificare questa istruzione.
L'esempio qui sotto presenta la sintassi di base dell'istruzione SELECT. La sintassi nella parte superiore di questa istruzione utilizza convenzioni simili a quelle utilizzate in altri manuali di programmazione. Le parole in maiuscolo sono le parole chiave che hai per digitare esattamente come mostrato. Al contrario, devi fornire sostituti alle parole minuscole. Ad esempio, puoi inserire un elenco di colonne al posto di select_list e puoi inserire un nome di tabella al posto di table_source. Oltre a ciò, puoi scegliere tra gli elementi in un riepilogo della sintassi che sono separati da barre verticali (I) e racchiusi tra parentesi graffe ({}) o parentesi quadre ([]). È possibile omettere gli elementi racchiusi tra parentesi. Se puoi scegliere tra due o più elementi opzionali, l'elemento predefinito è sottolineato. E se un elemento può essere codificato più volte in un'istruzione, è seguito da puntini di sospensione ( ... ). Vedrai esempi di barre verticali, parentesi graffe, valori predefiniti in questa lezione. Per ora, se confronti la sintassi in questo esempio con la codifica nell'esempio successivo, dovresti facilmente vedere come i due sono correlati. Il riepilogo della sintassi in questo esempio è stato semplificato in modo che tu possa concentrarti sulle quattro clausole principali dell'istruzione SELECT: SELECT, FROM, WHERE, e ORDER BY. La maggior parte delle istruzioni SELECT codificate le conterrà tutte e quattro. Tuttavia, è richiesta solo la clausola SELECT. La clausola SELECT è sempre la prima clausola in un'istruzione SELECT. Esso identifica le colonne che verranno incluse nel set di risultati. Queste colonne sono recuperate dalle tabelle di base denominate nella clausola FROM. Questa lezione si concentra sul recupero dei dati da una singola tabella. Le clausole FROM in tutte le istruzioni mostrate in questa lezione denominano una singola tabella di base. Nella prossima lezione imparerai come recuperare i dati da due o più tabelle. Le clausole WHERE e ORDER BY sono facoltative. La clausola ORDER BY determina il modo in cui vengono ordinate le righe nel set di risultati e la clausola WHERE determina quali righe nella tabella di base sono incluse nel set di risultati. La clausola WHERE specifica una condizione di ricerca utilizzata per filtrare le righe nella tabella di base. Questa condizione di ricerca può essere costituita da uno o più valori booleani espressioni o predicati. Un'espressione booleana è un'espressione che restituisce Vero o Falso. Quando la condizione di ricerca restituisce True, la riga è inclusa nel set di risultati. In questa lezione non utilizzerò i termini "espressione booleana" o "predicato" perché non penso che descrivano chiaramente il contenuto della clausola WHERE. Utilizzerò invece semplicemente il termine "condizione di ricerca" per riferirmi all'espressione che restituisce Vero o Falso.
SELECT select_list
[FROM table_source]
[WHERE search_condition]
[ORDER BY order_by_list]
L'esempio qui sotto presenta cinque esempi di istruzioni SELECT. Tutte queste istruzioni recuperano i dati dalla tabella Fatture. Se non hai familiarità con questa tabella, è necessario utilizzare Management Studio come descritto nell'ultima lezione. La prima istruzione in questa figura recupera tutte le righe e le colonne dalla tabella Fatture. Qui, un asterisco (*) viene utilizzato come abbreviazione per indicare che tutte le colonne devono essere recuperate e la clausola WHERE viene omessa in modo che non sono presenti condizioni sulle righe recuperate. Si noti che questa istruzione non include una clausola ORDER BY, quindi le righe sono nella sequenza delle chiavi primarie. Puoi vedere i risultati dopo questa istruzione così come vengono visualizzati da Management Studio. Si noti che sia le barre di scorrimento orizzontali che quelle verticali sono visualizzate, indicando che il set di risultati contiene più righe e colonne di quanto possa essere visualizzato sullo schermo contemporaneamente. La seconda istruzione recupera le colonne selezionate dalla tabella Fatture. Come puoi vedere, le colonne da recuperare sono elencate nella clausola SELECT. Come la prima istruzione, questa istruzione non include una clausola WHERE, quindi tutte le righe vengono recuperate. Quindi, la clausola ORDER BY fa sì che le righe vengano ordinate in base alla colonna InvoiceTotal in sequenza crescente. La terza istruzione elenca anche le colonne da recuperare. In questo caso, tuttavia, l'ultima colonna viene calcolata da due colonne nella tabella di base, CreditTotal e PaymentTotal e alla colonna risultante viene assegnato il nome TotalCredits. Inoltre, la clausola WHERE specifica che solo la fattura la cui colonna InvoiceID con un valore pari a 17 dovrebbe essere recuperata. La quarta istruzione SELECT include una clausola WHERE la cui condizione specifica un intervallo di valori. In questo caso, solo le fatture con date di fatturazione comprese tra 24/01/2023 e 31/01/2023 vengono recuperate. Inoltre, le righe nel set di risultati sono ordinati per data fattura. L'ultima istruzione in questo esempio mostra un'altra variazione della clausola WHERE. In questo caso, solo le righe con totali fatture superiori a 50.000 sono recuperate. Poiché nessuna delle righe nella tabella Fatture soddisfa questa condizione, il file il set di risultati è vuoto.
USE AP
GO
SELECT *
FROM Invoices;
USE AP
GO
SELECT InvoiceNumber, InvoiceDate, InvoiceTotal
FROM Invoices
ORDER BY InvoiceTotal;
USE AP
GO
SELECT InvoiceNumber, InvoiceDate, InvoiceTotal
FROM Invoices
WHERE InvoiceDate BETWEEN '2023-01-24' AND '2023-01-31'
ORDER BY InvoiceDate;
USE AP
GO
SELECT InvoiceNumber, InvoiceDate, InvoiceTotal
FROM Invoices
WHERE InvoiceTotal > 50000;
L'esempio qui sotto presenta una sintassi estesa per la clausola SELECT. Le parole chiave mostrate nella prima riga consentono di limitare le righe restituite tramite una interrogazione. Impariamo le varie tecniche per identificare quali colonne devono essere incluse in un insieme di risultati.
L'esempio qui sotto riassume le tecniche che è possibile utilizzare per codificare la specifiche colonne. Hai già visto come utilizzare alcune di queste tecniche in precedenza. Ad esempio, è possibile utilizzare un asterisco nella clausola SELECT da recuperare tutte le colonne nella tabella di base ed è possibile codificare un elenco di nomi di colonne separati da virgole. Tieni presente che quando codifichi un asterisco, le colonne sono restituite nell'ordine in cui si trovano nella tabella di base. È inoltre possibile codificare una specifica di colonna come espressione. Per esempio, è possibile utilizzare un'espressione aritmetica per eseguire un calcolo su due o più colonne nella tabella di base ed è possibile utilizzare un'espressione stringa per combinare due o più valori di stringa. Un'espressione può anche includere una o più funzioni. Scoprirai di più su ciascuna di queste tecniche negli argomenti che seguono. Ma prima dovresti sapere che quando codifichi la clausola SELECT, dovresti includere solo le colonne necessarie. Ad esempio, non dovresti utilizzare un asterisco per recuperare tutte le colonne a meno che non siano necessarie tutte le colonne. Questo è perché la quantità di dati recuperati può influire sulle prestazioni del sistema. Ciò è particolarmente importante se stai sviluppando istruzioni SQL che verranno utilizzate da programmi applicativi.
SELECT [ALL IDISTINCT] [TOP n [PERCENT] [WITH TIES]]
column_specification [[AS] result_column]
[, column_specification [[AS] result_column]] ...
Source | Option | Syntax |
---|---|---|
Valore della tabella di base | Tutte le colonne | * |
Nome della colonna | column_name | |
Valore calcolato | Risultato di un calcolo | Espressione aritmetica |
Risultato di una concatenazione | Espressione stringa | |
Risultato di una funzione | Funzione |
SELECT *
USE AP
GO
SELECT VendorName, VendorCity, VendorState
USE AP
GO
SELECT InvoiceNumber, (InvoiceTotal - PaymentTotal - CreditTotal) AS BalanceDue
USE AP
GO
SELECT vendorContactFName + ' ' + vendorContactLName AS FullName
USE AP
GO
SELECT InvoiceNumber, InvoiceDate, GETDATE () AS CurrentDate
Per impostazione predefinita, ad una colonna in un set di risultati viene assegnato lo stesso nome della colonna nel database. Tuttavia, se necessario, è possibile specificare un nome diverso. Potete anche denominare una colonna che contiene un valore calcolato. Quando lo fai, il nuovo nome della colonna viene chiamato alias di colonna. L'esempio qui sotto presenta due tecniche per creare alias di colonna. La prima tecnica consiste nel codificare la specifica della colonna seguita dalla parola chiave AS e l'alias della colonna. Questa è la tecnica di codifica standard ANSI e illustrata dal primo esempio. Qui viene aggiunto uno spazio tra le due parole nel nome della colonna InvoiceNumber, InvoiceDate la colonna viene modificata solo in Data e la colonna InvoiceTotal viene modificata in Totale. Nota che poiché uno spazio è incluso nel nome della prima colonna, è racchiuso tra parentesi quadre ([]). Come imparerai nella lezione 10, qualsiasi nome che non segua le regole di SQL Server per la denominazione degli oggetti deve essere racchiuso tra parentesi quadre o virgolette doppie. Gli alias di colonna possono anche essere racchiusi tra virgolette singole. Il secondo esempio in questa figura illustra un'altra tecnica per creare un alias di colonna. In questo caso la colonna viene assegnata a un alias utilizzando un segno di uguale. Questa tecnica è disponibile solo con SQL Server, non con altri tipi di database, ed è inclusa per compatibilità con le versioni precedenti di SQL Server. Potresti vedere questa tecnica utilizzata nel codice precedente, non la consiglio per le nuove dichiarazioni che scrivi. Il terzo esempio in questa figura illustra cosa succede quando non assegni un alias a una colonna calcolata. Qui non viene assegnato alcun nome alla colonna, che di solito non è quello che vuoi. Ecco perché di solito assegni un nome alle colonne calcolate da altre colonne nella tabella di base.
USE AP
GO
SELECT InvoiceNumber AS [Invoice Number], InvoiceDate AS Date,
InvoiceTotal AS Total
FROM Invoices;
USE AP
GO
SELECT [Invoice Number] = InvoiceNumber, Date = InvoiceDate,
Total = InvoiceTotal
FROM Invoices;
USE AP
GO
SELECT InvoiceNumber, InvoiceDate, InvoiceTotal,
(InvoiceTotal - PaymentTotal - CreditTotal)
FROM Invoices;
Un'espressione stringa è costituita da una combinazione di uno o più caratteri, colonne e valori letterali. Per combinare o concatenare colonne e valori, si utilizza l'operatore di concatenazione (+). Ciò è illustrato dagli esempi qui sotto. Il primo esempio mostra come concatenare le colonne VendorCity e VendorState nella tabella Fornitori. Si noti che poiché a questo non è assegnato alcun alias colonna, non ha un nome nel set di risultati. Si noti inoltre che i dati nella colonna VendorState viene visualizzata immediatamente dopo i dati in VendorCity colonna nei risultati. Ciò è dovuto al modo in cui VendorCity è definito nel database. Il secondo esempio mostra come formattare un'espressione stringa aggiungendo spazi e punteggiatura. Qui, la colonna VendorCity è concatenata con ad una stringa letterale, o costante stringa, che contiene una virgola e uno spazio. La colonna VendorState è concatenata con quel risultato, seguita da una stringa letterale che contiene un singolo spazio e la colonna VendorZipCode. Occasionalmente potrebbe essere necessario includere una virgoletta singola o un apostrofo all'interno di una stringa letterale. Se si digita semplicemente una virgoletta singola, tuttavia, il sistema lo interpreterà erroneamente come la fine della stringa letterale. Di conseguenza, devi codificare due virgolette di seguito. Ciò è illustrato dal terzo esempio.
USE AP
GO
SELECT VendorCity, VendorState, (VendorCity + ' ' + VendorState)
FROM Vendors;
USE AP
GO
SELECT VendorName, VendorCity + ', ' + VendorState + ' ' + VendorZipCode AS Address
FROM Vendors;
USE AP
GO
SELECT VendorName + '''s Address: ', (VendorCity + ', ' + VendorState + ' ' + VendorZipCode)
FROM Vendors;
USE AP
GO
SELECT VendorName + CONCAT(' Think', ' ', 'Green') AS 'Comportamento'
FROM Vendors;
USE AP
GO
DECLARE @Str1 AS VARCHAR(100)=' '
DECLARE @Str2 AS VARCHAR(100)='Think'
DECLARE @Str3 AS VARCHAR(100)='-'
DECLARE @Str4 AS VARCHAR(100)='green'
SELECT VendorName + CONCAT(@Str1,@Str2,@Str3,@Str4) AS 'Comportamento'
FROM Vendors;
L'esempio qui sotto mostra come codificare le espressioni aritmetiche. Per iniziare, riassumo i cinque operatori aritmetici che puoi utilizzare in questo tipo di espressione. Quindi, presento tre esempi che illustrano come utilizzare questi operatori. L'istruzione SELECT nel primo esempio include un'operazione aritmetica espressione che calcola il saldo dovuto per una fattura. Questa espressione sottrae le colonne PaymentTotal e CreditTotal dalla colonna InvoiceTotal. Alla colonna risultante viene assegnato il nome BalanceDue. Quando SQL Server valuta un'espressione aritmetica, esegue l'operazione le operazioni da sinistra a destra in base all'ordine di precedenza. Questo ordine dice che le operazioni di moltiplicazione, divisione e modulo vengono eseguite per prime, seguite da addizione e sottrazione. Se non è quello che vuoi, puoi usare le parentesi per specificare come si desidera che un'espressione venga valutata. Quindi, vengono valutate per prime le espressioni nelle parentesi più interne, seguite dalle espressioni in serie nelle parentesi esterne. All'interno di ciascuna serie di parentesi, l'espressione è valutata da sinistra a destra in ordine di precedenza. Puoi utilizzare anche le parentesi per chiarire un'espressione anche se non sono necessarie per valutare correttamente l'espressione. Per illustrare come le parentesi e l'ordine di precedenza influiscono sulla valutazione di un'espressione, si consideri il secondo esempio. Qui, le espressioni nella seconda e nella terza colonna utilizzano entrambe gli stessi operatori. Quando SQL Server valuta l'espressione nella seconda colonna, esegue l'operazione di moltiplicazione prima dell'operazione di addizione perché la moltiplicazione viene prima dell'addizione in ordine di precedenza. Quando SQL Server valuta l'espressione nella terza colonna, invece, esegue l'operazione di addizione prima perché è racchiusa tra parentesi. Come puoi vedere nel set di risultati mostrato, queste due espressioni danno come risultato valori diversi. Anche se probabilmente hai familiarità con l'addizione, la sottrazione, operatori di moltiplicazione e divisione, potresti non avere familiarità con l'operatore modulo. Questo operatore restituisce il resto di una divisione di due numeri interi. Ciò è illustrato nel terzo esempio in questa figura. La seconda colonna contiene un'espressione che restituisce il quoziente di un'operazione di divisione. Notare che il risultato della divisione di due numeri interi è sempre un numero intero. Imparerai di più al riguardo nella lezione 8. La terza colonna contiene un'espressione che restituisce il resto dell'operazione di divisione. Se studi questo esempio per un minuto, dovresti vedere rapidamente come funziona.
* | Moltiplicazione |
/ | Divisione |
% | Modulo |
+ | Addizione |
- | Sottrazione |
USE AP
GO
SELECT InvoiceTotal, PaymentTotal, CreditTotal, (InvoiceTotal - PaymentTotal - CreditTotal) AS BalanceDue
FROM Invoices;
USE AP
GO
SELECT InvoiceID, InvoiceID + 7 * 3 AS OrderOfPrecedence, (InvoiceID + 7 ) * 3 AS AddFirst
FROM Invoices
ORDER BY InvoiceID;
USE AP
GO
SELECT InvoiceID,
InvoiceID / 10 AS Quotient,
InvoiceID % 10 AS Remainder
FROM Invoices
ORDER BY InvoiceID;
Lesempio qui sotto presenta le funzioni e illustra come utilizzarle nelle specifiche di colonna. Una funzione esegue un'operazione e restituisce un valore. Per ora, non preoccuparti dei dettagli su come funzionano le funzioni mostrate qui. Scoprirai di più su tutte queste funzioni nella lezione 9. Concentrati invece solo sul come vengono utilizzate nelle specifiche delle colonne. Per codificare una funzione, si inizia inserendo il suo nome seguito da una serie di parentesi. Se la funzione richiede uno o più parametri, inseriscili tra parentesi e separarli con virgole. Quando inserisci un parametro, è necessario assicurarsi che abbia il tipo di dati corretto. Imparerai di più al riguardo nella lezione 9. Il primo esempio mostra come utilizzare la funzione LEFT per estrarre il primo carattere delle colonne VendorContactFName e VendorContactLName. Il primo parametro di questa funzione specifica il valore della stringa e il il secondo parametro specifica il numero di caratteri da restituire. I risultati delle due funzioni vengono quindi concatenati per formare le iniziali come mostrato nel set di risultati per questa istruzione. Il secondo esempio mostra come utilizzare la funzione CONVERT per modificare il tipo di dati di un valore. Questa funzione richiede due parametri. Il primo parametro specifica il nuovo tipo di dati e il secondo parametro specifica il valore da convertire. Inoltre, questa funzione accetta un terzo parametro opzionale che specifica il formato del valore restituito. La prima funzione CONVERT mostrata qui, ad esempio, converte la colonna PaymentDate in un valore di carattere con il formato gg/mm/aa. E la seconda funzione CONVERT converte PaymentTotal su un valore di carattere a lunghezza variabile formattato con virgole. Queste funzioni sono incluse in un'espressione stringa che concatena i relativi valori restituiti con la colonna InvoiceNumber e tre valori letterali. Il terzo esempio utilizza due funzioni che funzionano con le date. Il primo, GETDATE, restituisce la data corrente. Si noti che sebbene questa funzione accetta parametri, le parentesi sono comunque incluse. La seconda funzione, DATEDIFF, ottiene la differenza tra due valori di data. Questa funzione richiede tre parametri. Il primo specifica le unità in cui sarà il risultato espresso. In questo esempio, la funzione restituirà il numero di giorni tra due date. Il secondo e il terzo parametro specificano la data di inizio e la data di fine. Qui, il secondo parametro è la data della fattura e il terzo parametro lo è la data corrente, che si ottiene utilizzando la funzione GETDATE.
USE AP
GO
SELECT VendorContactFName, VendorContactLName,
LEFT (VendorContactFName, 1 ) +
LEFT (VendorContactLName, 1 ) AS Initials
FROM Vendors;
USE AP
GO
SELECT 'Invoice: #' + InvoiceNumber
+ ' data ' + CONVERT(VARCHAR (10), InvoiceDate, 103)
+ ' per € ' + FORMAT(InvoiceTotal, '#,###.00', 'it-IT')
AS Invoice
FROM Invoices;
USE AP
GO
SELECT InvoiceDate,
GETDATE () AS 'Today''s Date',
DATEDIFF (day, InvoiceDate, GETDATE ()) AS Age
FROM Invoices;
Per impostazione predefinita, tutte le righe nella tabella di base che soddisfano la condizione di ricerca specificata nella clausola WHERE sono inclusi nel set di risultati. In alcuni casi, tuttavia, ciò significa che il set di risultati conterrà righe duplicate o righe dove i valori delle colonne sono identici. Se non è quello che desideri, puoi includere la parola chiave DISTINCT nella clausola SELECT per eliminare le righe duplicate. L'esempio qui sotto illustra come funziona. Qui, entrambe le istruzioni SELECT recuperano le colonne VendorCity e VendorState dalla tabella Vendors. la prima istruzione, tuttavia, non include la parola chiave DISTINCT. A causa di ciò, la stessa città e lo stesso stato possono apparire più volte nel set di risultati. Nei risultati mostrati in questo esempio, puoi vedere che si verifica Anaheim CA due volte e Boston MA si verifica tre volte. Al contrario, se la stessa istruzione include la parola chiave DISTINCT, è inclusa ogni combinazione città/stato solo una volta. Si noti che, oltre a includere la parola chiave DISTINCT, la seconda istruzione non include la clausola ORDER BY. Questo perché quando includi la parola chiave DISTINCT, il set di risultati viene automaticamente ordinato in base alla prima colonna. In questo caso, si tratta della stessa colonna utilizzata per ordinare il set di risultati restituito dalla prima istruzione.
USE AP
GO
SELECT VendorCity, VendorState
FROM Vendors
ORDER BY VendorCity;
USE AP
GO
SELECT DISTINCT VendorCity, VendorState
FROM Vendors;
Oltre ad eliminare le righe duplicate, è possibile limitare il numero di righe recuperate da un'istruzione SELECT. A tale scopo, si utilizza la clausola TOP. L'esempio qui sotto mostra come fare. La clausola TOP può essere utilizzata in due modi. In primo luogo, si può usare per recuperare un numero specifico di righe dall'inizio, o dalla cima, dell'insieme dei risultati. A tale scopo, si codifica la parola chiave TOP seguita da un valore intero che specifica il numero di righe da restituire. Questo è illustrato nel primo esempio. Qui vengono restituite solo cinque righe. Si noti che questa istruzione include anche una clausola ORDER BY che ordina le righe in base alla colonna InvoiceTotal in sequenza decrescente. In questo modo, verranno restituite le fatture con i totali più alti. È inoltre possibile utilizzare la clausola TOP per recuperare una percentuale specifica di righe nel set di risultati. A tale scopo, si deve includere la parola chiave PERCENT, come mostrato nel secondo esempio. In questo caso, il set di risultati include sei righe, ovvero il cinque percento delle righe totali. Per impostazione predefinita, la clausola TOP consente di recuperare il numero esatto o la percentuale di righe specificate. Tuttavia, se altre righe corrispondono ai valori dell'ultima riga, è possibile includerle includendo WITH TIES nella clausola TOP. Questo è illustrato nel terzo esempio. In questo caso, l'istruzione SELECT dice di recuperare le prime cinque righe da un insieme di risultati che include le colonne VendorID e InvoiceDate ordinate in base alla colonna InvoiceDate. Come si può vedere, però, l'insieme dei risultati include sei righe invece di cinque. Questo perché WITH TIES è incluso nella clausola TOP e le colonne della sesta riga hanno gli stessi valori delle colonne della quinta riga.
USE AP
GO
SELECT TOP 5 VendorID, InvoiceTotal
FROM Invoices
ORDER BY InvoiceTotal DESC;
USE AP
GO
SELECT TOP 5 PERCENT VendorID, InvoiceTotal
FROM Invoices
ORDER BY InvoiceTotal DESC;
USE AP
GO
SELECT TOP 5 WITH TIES vendorID, InvoiceDate
FROM Invoices
ORDER BY InvoiceDate ASC;
All'inizio di questa lezione ho detto che, per migliorare le prestazioni, bisogna codificare le istruzioni SELECT in modo che recuperino solo le colonne necessarie. Questo vale anche per il recupero delle righe: meno righe si recuperano, più efficiente sarà l'istruzione. Per questo motivo, nelle istruzioni SELECT c'è quasi sempre presente una clausola WHERE con una condizione di ricerca che filtra le righe della tabella di base in modo da recuperare solo le righe necessarie. Negli argomenti che seguono verranno illustrati diversi modi per codificare questa clausola.
L'esempio qui sotto mostra come utilizzare gli operatori di confronto nella condizione di ricerca di una clausola WHERE. Come si può vedere nel riepilogo della sintassi nella prima parte degli esempi, si utilizza un operatore di confronto per confrontare due espressioni. Se il risultato del confronto è Vero, la riga in esame viene inclusa nei risultati della query. Gli esempi qui sotto mostrano come utilizzare alcuni degli operatori di confronto. La prima clausola WHERE, ad esempio, utilizza l'operatore equal (=) per recuperare solo le righe la cui colonna VendorState ha un valore IA. Poiché il codice di stato è un letterale di stringa, deve essere incluso tra apici singoli. Al contrario, il letterale numerico utilizzato nella seconda clausola WHERE non è racchiuso tra virgolette. Questa clausola utilizza l'operatore maggiore di (>) per recuperare solo le righe che hanno un saldo dovuto maggiore di zero. La terza clausola WHERE illustra un altro modo per recuperare tutte le fatture con un saldo dovuto. Come la seconda clausola, utilizza l'operatore maggiore di. Tuttavia, invece di confrontare il saldo dovuto con un valore pari a zero, confronta il totale della fattura con il totale dei pagamenti e dei crediti applicati alla fattura. La quarta clausola WHERE illustra come sia possibile utilizzare operatori di confronto diversi dall'operatore uguale con dati stringa. In questo esempio, l'operatore mirore di (<) viene utilizzato per confrontare il valore della colonna VendorName con una stringa letterale contenente la lettera M. In questo modo la query restituirà tutti i venditori con nomi che iniziano con le lettere da A a L. È possibile utilizzare gli operatori di confronto anche con letterali di data, come illustrato dalle clausole WHERE quinta e sesta. La quinta clausola recupera le righe con date di fatturazione uguali o precedenti al 31 maggio 2016, mentre la sesta clausola recupera le righe con date di fatturazione uguali o successive al 1° maggio 2016. Come i letterali di stringa, anche quelli di data devono essere racchiusi tra apici singoli. Inoltre, è possibile utilizzare diversi formati per specificare le date, come mostrato dai due letterali di data mostrati in questa figura. Per saperne di più sui formati di data accettabili, si veda la lezione 8. L'ultima clausola WHERE mostra come testare una condizione diverso da. Per farlo, si codifica un segno meno di seguito da un segno maggiore di. In questo caso, verranno recuperate solo le righe con un totale di crediti non uguale a zero. Quando è possibile, si dovrebbero confrontare espressioni con tipi di dati simili. Se si tenta di confrontare espressioni con tipi di dati diversi, SQL Server può convertire implicitamente il tipo di dati. Spesso questa conversione è implicita è accettata. Tuttavia, le conversioni implicite possono occasionalmente dare risultati inaspettati. In questo caso, è possibile utilizzare la funzione CONVERT o la funzione CAST, che verrà illustrata nella lezione 8, per convertire esplicitamente i tipi di dati in modo che il confronto produca i risultati desiderati.
WHERE expression_l operator expression_2
= | Uguale a |
> | Maggiore di |
< | Minore di |
<= | Minore uguale a |
>= | Maggiore uguale a |
<> | Diverso da |
USE AP
GO
SELECT TOP 100 PERCENT VendorID, VendorName, VendorCity, VendorState
FROM Vendors
WHERE VendorState = 'IA'
USE AP
GO
SELECT TOP 100 PERCENT InvoiceNumber, InvoiceTotal, PaymentTotal, CreditTotal
FROM Invoices
WHERE (InvoiceTotal - PaymentTotal - CreditTotal) > 0
USE AP
GO
SELECT TOP 100 PERCENT InvoiceNumber, InvoiceTotal, PaymentTotal, CreditTotal
FROM Invoices
WHERE InvoiceTotal > (PaymentTotal + CreditTotal)
USE AP
GO
SELECT TOP 100 PERCENT VendorID, VendorName, VendorCity, VendorState
FROM Vendors
WHERE VendorName < 'M'
USE AP
GO
SELECT TOP 100 PERCENT InvoiceNumber, InvoiceTotal, PaymentTotal, CreditTotal, InvoiceDate
FROM Invoices
WHERE InvoiceDate <= '2022-12-31'
USE AP
GO
SELECT TOP 100 PERCENT InvoiceNumber, InvoiceTotal, PaymentTotal, CreditTotal, InvoiceDate
FROM Invoices
WHERE InvoiceDate >= '2023-01-01'
USE AP
GO
SELECT TOP 100 PERCENT InvoiceNumber, InvoiceTotal, PaymentTotal, CreditTotal, InvoiceDate
FROM Invoices
WHERE CreditTotal <> 0
L'esempio qui sotto mostra come utilizzare gli operatori logici in una clausola WHERE. È possibile utilizzare gli operatori AND e OR per combinare due o più condizioni di ricerca in una condizione composta. È inoltre possibile utilizzare l'operatore NOT per negare una condizione di ricerca. Gli esempi di questa figura illustrano il funzionamento di questi operatori. I primi due esempi illustrano la differenza tra gli operatori AND e OR. Quando si usa l'operatore AND, entrambe le condizioni devono essere vere. Nel primo esempio vengono recuperati dalla tabella Vendors solo i venditori del New Jersey i cui acquisti dell'anno precedente sono superiori a 200. Quando si usa l'operatore OR, invece, solo una delle condizioni deve essere vera. Quindi, nel secondo esempio, vengono recuperati tutti i venditori del New Jersey e tutti i venditori i cui acquisti dell'anno precedente sono superiori a 200. Il terzo esempio mostra una condizione composta che utilizza due operatori NOT. Come si può notare, questa espressione è piuttosto difficile da capire. Per questo motivo, e poiché l'uso dell'operatore NOT può ridurre le prestazioni del sistema, si dovrebbe evitare di usarlo quando possibile. Il quarto esempio di questa figura, ad esempio, mostra come la condizione di ricerca del terzo esempio possa essere riformulata per eliminare l'operatore NOT. Si noti che la condizione del quarto esempio è molto più facile da capire. Gli ultimi due esempi di questa figura mostrano come l'ordine di precedenza degli operatori logici e l'uso delle parentesi influenzino il risultato di una condizione di ricerca. Per impostazione predefinita, l'operatore NOT viene valutato per primo, seguito da AND e poi da OR. Tuttavia, è possibile utilizzare le parentesi per annullare l'ordine di precedenza o per chiarire un'espressione logica, proprio come si fa con le espressioni aritmetiche. Nel penultimo esempio, ad esempio, non vengono utilizzate parentesi, quindi le due condizioni collegate dall'operatore AND vengono valutate per prime. Nell'ultimo esempio, invece, vengono utilizzate le parentesi, in modo che le due condizioni collegate dall'operatore OR vengano valutate per prime. Se dedicate un minuto per rivedere i risultati mostrati in questa figura, dovreste essere in grado di vedere come queste due condizioni differiscono.
WHERE [NOT] search_condition_l {AND IOR} [NOT] search_condition 2 ...
USE AP
GO
SELECT TOP 100 PERCENT VendorID, VendorName, VendorCity, VendorState
FROM Vendors
WHERE VendorState = 'NJ' AND VendorName < 'S'
USE AP
GO
SELECT TOP 100 PERCENT VendorID, VendorName, VendorCity, VendorState
FROM Vendors
WHERE VendorState = 'NJ' OR VendorName < 'B'
USE AP
GO
SELECT TOP 100 PERCENT InvoiceNumber, InvoiceTotal, PaymentTotal, CreditTotal, InvoiceDate
FROM Invoices
WHERE NOT (InvoiceTotal <= 2000 OR NOT InvoiceDate <= '2022-11-30')
USE AP
GO
SELECT TOP 100 PERCENT InvoiceNumber, InvoiceTotal, PaymentTotal, CreditTotal, InvoiceDate
FROM Invoices
WHERE InvoiceTotal > 2000 AND InvoiceDate <= '2022-11-30'
USE AP
GO
SELECT TOP 100 PERCENT InvoiceNumber, InvoiceTotal, PaymentTotal, CreditTotal, InvoiceDate
FROM Invoices
WHERE InvoiceDate >= '01/01/2023'
AND InvoiceTotal - PaymentTotal - CreditTotal > 0 -- fatture non saldate
OR InvoiceTotal > 5000
USE AP
GO
SELECT TOP 100 PERCENT InvoiceNumber, InvoiceTotal, PaymentTotal, CreditTotal, InvoiceDate
FROM Invoices
WHERE (InvoiceDate >= '01/01/2023'
AND InvoiceTotal - PaymentTotal - CreditTotal > 0) -- fatture non saldate
OR InvoiceTotal > 5000
L'esempio qui sotto mostra come codificare una clausola WHERE che utilizza l'operatore IN. Quando si utilizza questo operatore, il valore dell'espressione di test viene confrontato con l'elenco di espressioni della frase IN. Se l'espressione di prova è uguale a una delle espressioni dell'elenco, la riga viene inclusa nei risultati della query. Questo è illustrato dal primo esempio, che restituirà tutte le righe la cui colonna TermsID è uguale a 1, 3 o 4. Si può anche usare l'operatore NOT con l'operatore IN per verificare se un valore non è presente in un elenco di espressioni. Questo è illustrato dal secondo esempio in. In questo caso, vengono recuperati solo i venditori che non si trovano in California, Nevada o Oregon. Se si osserva la sintassi della frase IN mostrata nella parte superiore, si nota che è possibile codificare una sottoquery al posto di un elenco di espressioni. Le sottoquery sono uno strumento potente che verrà illustrato in dettaglio nella lezione 6. Per ora, però, è bene sapere che una sottoquery è semplicemente un'istruzione SELECT all'interno di un'altra istruzione. Nel terzo esempio, per esempio, una subquery viene utilizzata per restituire un elenco di valori dell'ID fornitore per i venditori che hanno fatture con data > 1 gennaio 2023. Quindi, la clausola WHERE recupera una riga di un venditore solo se il fornitore è presente nell'elenco. Per funzionare, la sottoquery deve restituire una singola colonna, in questo caso VendorID.
WHERE test_expression [NOT] IN ({subquery expression_l [, expression_2] ... })
USE AP
GO
SELECT TOP 100 PERCENT InvoiceNumber, VendorID, InvoiceTotal,
PaymentTotal, CreditTotal, InvoiceDate, TermsID
FROM Invoices
WHERE TermsID IN (1, 3, 4)
USE AP
GO
SELECT TOP 100 PERCENT VendorID, VendorName, VendorCity, VendorState
FROM Vendors
WHERE VendorState NOT IN ('CA', 'NV', 'OR', 'WI', 'DC')
USE AP
GO
SELECT TOP 100 PERCENT VendorID, VendorName, VendorCity, VendorState
FROM Vendors
WHERE vendorID IN
(
SELECT VendorID
FROM Invoices
WHERE InvoiceDate > '2023-01-01'
)
L'esempio qui sotto mostra come utilizzare l'operatore BETWEEN in una clausola WHERE. Quando si utilizza questo operatore, il valore di un'espressione di test viene confrontato con l'intervallo di valori specificato nell'istruzione BETWEEN. Se il valore rientra in questo intervallo, la riga viene inclusa nei risultati della query. Il primo esempio, mostra una semplice clausola WHERE che utilizza l'operatore BETWEEN. Essa recupera le fatture con data di fatturazione compresa tra il 25/12/2022 e il 06/01/2023. Si noti che l'intervallo è inclusivo, quindi le fatture con date di fatturazione del 25/12/2022 del 06/01/2023 sono incluse nei risultati. Il secondo esempio mostra come utilizzare l'operatore NOT per selezionare le righe che non rientrano in un determinato intervallo. In questo caso, i venditori con codice postale non compreso tra 93600 e 93799 sono inclusi nei risultati. Il terzo esempio mostra come utilizzare un valore calcolato nell'espressione di test. In questo caso, le colonne PaymentTotal e CreditTotal vengono sottratte dalla colonna InvoiceTotal per ottenere il saldo dovuto. Quindi, questo valore viene confrontato con l'intervallo specificato nella frase BETWEEN. L'ultimo esempio mostra come sia possibile utilizzare valori calcolati nella frase BETWEEN. In questo caso, il primo valore è il risultato della funzione GETDATE, e il secondo valore è il risultato della funzione GETDATE più 30 giorni. Quindi i risultati della query includeranno tutte le fatture con scadenza compresa tra la data attuale e 30 giorni dalla data corrente.
WHERE test_expression [NOT] BETWEEN begin_expression AND end_expression
USE AP
GO
SELECT TOP 100 PERCENT InvoiceNumber, VendorID, InvoiceTotal,
PaymentTotal, CreditTotal, InvoiceDate
FROM Invoices
WHERE InvoiceDate BETWEEN '2016-05-01' AND '2016-05-31'
USE AP
GO
SELECT TOP 100 PERCENT VendorID, VendorName, VendorCity, VendorState, vendorZipCode
FROM Vendors
WHERE vendorZipCode NOT BETWEEN 20090 AND 94244
ORDER BY vendorZipCode
USE AP
GO
SELECT TOP 100 PERCENT InvoiceNumber, VendorID, InvoiceTotal,
PaymentTotal, CreditTotal, InvoiceDate
FROM Invoices
WHERE (InvoiceTotal - PaymentTotal - CreditTotal) BETWEEN 50 AND 1000
USE AP
GO
-- insert Invoice
INSERT Invoices
(VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, PaymentTotal, CreditTotal, TermsID, InvoiceDueDate, PaymentDate)
VALUES (122, N'989319-499', CAST(N'2025-02-26' AS Date), 4000.00, 4000.00, 0.0000, 3, CAST(N'2025-03-10' AS Date), CAST(N'2025-03-15' AS Date))
GO
SELECT TOP 100 PERCENT InvoiceNumber, VendorID, InvoiceTotal, PaymentTotal, CreditTotal, InvoiceDate, InvoiceDueDate
FROM Invoices
WHERE InvoiceDueDate BETWEEN GetDate() AND GetDate() + 30
Un ultimo operatore che si può usare in una condizione di ricerca è l'operatore LIKE mostrato nell'esempio qui sotto. Questo operatore, insieme ai caratteri jolly mostrati all'inizio di questo esempio, viene utilizzato per specificare un modello di stringa, o maschera, che si desidera confrontare. Gli esempi mostrati in questa figura ne illustrano il funzionamento. Nel primo esempio, l'operatore LIKE specifica che devono essere inclusi tutti i fornitori di città, che iniziano con le lettere SAN, devono essere inclusi nei risultati della query. In questo caso, il (%) indica che qualsiasi carattere può seguire queste tre lettere. Quindi San Diego e Santa Ana sono entrambe incluse nei risultati. Il secondo esempio seleziona tutti i fornitori il cui nome inizia con le lettere COMPU, seguito da un carattere qualsiasi, dalle lettere ER e da tutti i caratteri successivi. Due nomi di fornitori che corrispondono a questo schema sono Compuserve e Computerworld. Il terzo esempio ricerca i valori della colonna VendorContactLName per un nome che può essere scritto in due modi diversi: Damien o Damion. Per per fare ciò, la maschera specifica i due possibili caratteri in quinta posizione, E e O, tra parentesi. Il quarto esempio utilizza le parentesi per specificare un intervallo di valori. In questo caso, la colonna VendorState viene cercata per i valori che iniziano con la lettera N e finiscono con qualsiasi lettera da A a J. Questo esclude stati come Nevada (NV) e New York (NY). Il quinto esempio mostra come utilizzare il caret(^) per escludere uno o più caratteri dallo schema. In questo caso, lo schema dice che il valore della colonna VendorState deve iniziare con la lettera N, ma non deve terminare con le lettere da K a Y. Questo produce lo stesso risultato dell'istruzione precedente. L'ultimo esempio di questa figura mostra come utilizzare l'operatore NOT con l'operatore LIKE. La condizione in questo esempio verifica la presenza nella colonna VendorZipCode di valori per i valori che non iniziano con i numeri da 1 a 9. Il risultato sono tutti i codici di avviamento postale che iniziano con il numero 0. L'operatore LIKE è una tecnica potente per trovare informazioni in un database che non possono essere trovate con nessun'altra tecnica. Si tenga presente, tuttavia, che questa tecnica richiede molto overhead e può ridurre le prestazioni del sistema. Per questo motivo, si dovrebbe evitare di usare l'operatore LIKE nel codice SQL di produzione, quando possibile. Se è necessario effettuare una ricerca nel testo memorizzato nel database, un'opzione migliore è quella di utilizzare la funzione Full-Text Search fornita da SQL Server. Questa funzione fornisce metodi più potenti e flessibili per la ricerca di testo, e funziona in modo più efficiente dell'operatore LIKE. Tuttavia, la ricerca Full-Text Search è una funzione avanzata che richiede una certa configurazione e amministrazione e che è troppo complessa per essere spiegata in questa sede. Per ulteriori informazioni, è possibile consultare la voce “Ricerca full-text” nella documentazione di documentazione di SQL Server.
WHERE match_expression [NOT] LIKE pattern
Simbolo | Descrizione |
---|---|
% | Corrisponde a qualsiasi stringa di zero o più caratteri. |
_ | Corrisponde a qualsiasi singolo carattere. |
[ ] | Corrisponde a un singolo carattere elencato tra le parentesi. |
[ - ] | Corrisponde a un singolo carattere all'interno dell'intervallo indicato. |
[ ^ ] | Corrisponde a un singolo carattere non elencato dopo il trattino. |
Esempio | Risultati che corrispondono alla maschera |
---|---|
WHERE VendorCity LIKE 'SAN%' | "San Diego" and "Santa Ana". |
WHERE VendorName LIKE 'COMPU_ER%' | 'Compuserve' e 'Computerworld'. |
WHERE vendorContactLName LIKE 'DAMI[EO]N' | 'Damien' e 'Damion' |
WHERE vendorState LIKE 'N[A-J]' | 'NC' e 'NJ' ma non 'NV' o 'NY'. |
WHERE vendorState LIKE 'N[^K-Y]' | 'NC' e 'NJ' ma non 'NV' o 'NY' |
WHERE vendorZipCode NOT LIKE '[1-9]%' | '02107' e '08816' |
USE AP
GO
SELECT TOP 10 VendorID, VendorName, VendorCity, VendorState, vendorZipCode
FROM Vendors
WHERE VendorName LIKE 'a%'
ORDER BY VendorName
USE AP
GO
SELECT TOP 10 VendorID, VendorName, VendorCity, VendorState, vendorZipCode
FROM Vendors
WHERE VendorName COLLATE SQL_Latin1_General_CP1_CS_AS LIKE 'a%'
ORDER BY VendorName
USE AP
GO
SELECT TOP 10 VendorID, VendorName, VendorCity, VendorState, vendorZipCode
FROM Vendors
WHERE VendorName COLLATE SQL_Latin1_General_CP1_CS_AS LIKE 'A%'
ORDER BY VendorName
Nella prima lezione si è appreso che una colonna può contenere un valore nullo. Un valore nullo non è uguale a zero, a una stringa vuota che contiene uno o più spazi ( ' ' ) o a una stringa vuota ( '' ). Un valore nullo indica invece che i dati non sono applicabili, non disponibile o sconosciuto. Quando si ammettono valori nulli in una o più colonne, è necessario sapere come verificarli nelle condizioni di ricerca. A tale scopo, è possibile utilizzare la clausola IS NULL, come mostrato nell'esempio qui sotto. Questo esempio utilizza una tabella denominata NullSample per illustrare la ricerca di valori nulli. Questa tabella contiene due colonne. La prima colonna, InvoiceID, è una colonna di identità. La seconda colonna, InvoiceTotal, contiene il totale della fattura, che può essere un valore nullo. Come si può vedere nel primo esempio, la fattura con InvoiceID 3 contiene un valore nullo. Il secondo esempio in questa figura mostra cosa succede quando si recuperano tutte le fatture con un totale di fattura uguale a zero. Si noti che la riga che ha un totale della fattura nullo non viene inclusa nel set di risultati. Allo stesso modo, non sono incluse nell'insieme di risultati le fatture con totali di fattura non uguali a zero, come illustrato dal terzo esempio. Invece, è necessario utilizzare la clausola IS NULL per recuperare le righe con valori nulli, come mostrato nel quarto esempio. È anche possibile utilizzare l'operatore NOT con la clausola IS NULL, come illustrato nell'ultimo esempio. Quando si utilizza questo operatore, tutte le righe che non contengono valori nulli vengono incluse nei risultati della query.
USE AP
GO
-- create the NullSample table
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE NullSample (
InvoiceID int IDENTITY(1,1) NOT NULL,
InvoiceTotal money NULL
)
GO
USE AP
GO
INSERT NullSample (InvoiceTotal)
VALUES
(125.00),
(0.00),
(NULL),
(2199.99),
(0.00)
USE AP
GO
SELECT *
FROM NullSample
USE AP
GO
SELECT *
FROM NullSample
WHERE InvoiceTotal = 0
USE AP
GO
SELECT *
FROM NullSample
WHERE InvoiceTotal <> 0
USE AP
GO
SELECT *
FROM NullSample
WHERE InvoiceTotal IS NULL
USE AP
GO
SELECT *
FROM NullSample
WHERE InvoiceTotal IS NOT NULL
La clausola ORDER BY specifica l'ordine delle righe in un set di risultati. Nella maggior parte dei casi, è possibile utilizzare i nomi delle colonne della tabella di base per specificare l'ordine di ordinamento. Tuttavia, è possibile utilizzare anche altre tecniche per ordinare le righe in un insieme di risultati. Inoltre, è possibile utilizzare le nuove clausole OFFSET e FETCH della clausola ORDER BY per recuperare un intervallo di righe dall'insieme di risultati ordinato.
L'esempio qui sotto presenta la sintassi estesa della clausola ORDER BY. Come si può vedere, è possibile ordinare in base a una o più espressioni in ordine crescente o sequenza ascendente o discendente. Ciò è illustrato dai tre esempi qui sotto. I primi due esempi mostrano come ordinare le righe di un set di risultati in base a una singola colonna. Nel primo esempio, le righe della tabella Vendors vengono ordinate in sequenza ascendente in base alla colonna VendorName. Poiché la sequenza predefinita è quella ascendente, la parola chiave ASC viene omessa. Nel secondo esempio, le righe sono ordinate in ordine decrescente in base alla colonna VendorName. Per ordinare in base a più colonne, è sufficiente elencare i nomi nella clausola ORDER BY separati da virgole, come mostrato nel terzo esempio. In questo caso, le righe della tabella Vendors sono ordinate prima in base alla colonna VendorState in ordine crescente. Poi, all'interno di ogni stato, le righe vengono ordinate in base alla colonna VendorCity in sequenza crescente. Infine, all'interno di ogni città, le righe sono ordinate in base alla colonna VendorName in ordine crescente. Questo può essere definito un ordinamento perché un ordinamento è annidato all'interno di un altro. Anche se in questo esempio tutte le colonne sono ordinate in sequenza ascendente, non è detto che sia così. Ad esempio, avrei potuto ordinare la colonna VendorName in sequenza decrescente in questo modo: ORDER BY VendorState, VendorCity, vendorName DESC Si noti che la parola chiave DESC in questo esempio si applica solo alla colonna VendorName. Le colonne VendorState e VendorCity sono ancora ordinate in sequenza ascendente.
ORDER BY expression [ASC IDESC] [, expression [ASC IDESC]] ...
USE AP
GO
SELECT VendorName,
vendorCity + ', ' + vendorState + ' ' + vendorZipCode AS Address
FROM Vendors
ORDER BY VendorName
USE AP
GO
SELECT VendorName,
vendorCity + ', ' + vendorState + ' ' + vendorZipCode AS Address
FROM Vendors
ORDER BY VendorName DESC
USE AP
GO
SELECT VendorName,
VendorCity + ', ' + VendorState + ' ' + VendorZipCode AS Address
FROM Vendors
ORDER BY VendorState, VendorCity, VendorName
L'esempio qui sotto presenta altre tre tecniche per specificare l'ordinamento delle colonne. Innanzitutto, si può usare un alias di colonna definito nella clausola SELECT. La prima istruzione SELECT di questa figura, ad esempio, ordina in base a una colonna denominata Address, che è un alias per la concatenazione delle colonne VendorCity, VendorState e VendorZipCode. All'interno della colonna Indirizzo, l'insieme dei risultati è anche ordinato in base alla colonna VendorName. È possibile utilizzare anche un'espressione aritmetica o di stringa nella clausola ORDER BY, come illustrato nel secondo esempio. In questo caso, l'espressione consiste nella colonna VendorContactLName concatenata con la colonna VendorContactFName. In questo caso, nessuna delle due colonne è inclusa nella clausola SELECT. Sebbene SQL Server consenta questa tecnica di codifica raramente utilizzata, molti altri sistemi di database non la consentono. L'ultimo esempio di questa figura mostra come sia possibile utilizzare i numeri di colonna per per specificare un ordine. Per utilizzare questa tecnica, si codifica il numero che corrisponde alla colonna dell'insieme di risultati, dove 1 è la prima colonna, 2 la seconda e così via. In questo esempio, la clausola ORDER BY ordina l'insieme dei risultati in base alla seconda colonna, che contiene il nome del gruppo che contiene l'indirizzo concatenato, quindi dalla prima colonna, che contiene il nome del fornitore. Tuttavia, l'istruzione che utilizza i numeri di colonna è più difficile da leggere, perché bisogna guardare la clausola SELECT per vedere a quali colonne si riferiscono i numeri. Inoltre, se si aggiungono o rimuovono colonne dalla clausola SELECT è necessario modificare anche la clausola ORDER BY per riflettere la nuova posizione delle colonne. Di conseguenza, si dovrebbe evitare di utilizzare questa tecnica.
USE AP
GO
SELECT VendorName, VendorCity + ', ' + VendorState + ' ' + VendorZipCode AS Address
FROM Vendors
ORDER BY Address, VendorName
USE AP
GO
SELECT VendorName, VendorCity + ', ' + VendorState + ' ' + VendorZipCode AS Address
FROM Vendors
ORDER BY VendorContactLName + VendorContactFName
USE AP
GO
SELECT VendorName, VendorCity + ', ' + VendorState + ' ' + VendorZipCode AS Address
FROM Vendors
ORDER BY 2, 1
All'inizio di questa lezione, si è visto come utilizzare la clausola TOP per restituire un sottoinsieme delle righe selezionate da una query. Quando si usa questa clausola, le righe sono sempre dall'inizio dell'insieme di risultati. Al contrario, le nuove clausole OFFSET e FETCH consentono di restituire un sottoinsieme di righe a partire da qualsiasi punto dell'insieme di risultati ordinati. L'esempio qui sotto illustra il funzionamento di queste clausole. Il primo esempio mostra come utilizzare le clausole OFFSET e FETCH per recuperare le righe dall'inizio di un insieme di risultati. In questo caso, vengono recuperate le prime cinque righe. Il secondo esempio, invece, recupera dieci righe dall'insieme di risultati a partire dall'undicesima. Si noti che la clausola FETCH nel primo esempio utilizza la parola chiave FIRST, mentre la clausola FETCH del secondo esempio utilizza la parola chiave NEXT. Sebbene queste parole chiave siano intercambiabili, in genere vengono utilizzate come mostrato qui. È anche possibile restituire tutte le righe alla fine di un set di risultati dopo aver saltato il numero di righe specificato. Per farlo, basta omettere la clausola FETCH. Per esempio, se si omette questa clausola dal secondo esempio di questa figura vengono restituite le righe 11 fino alla fine del set di risultati. Le clausole OFFSET e FETCH sono particolarmente utili quando un'applicazione client deve recuperare ed elaborare una pagina di dati alla volta. Ad esempio, supponiamo che un'applicazione possa lavorare con un massimo di 20 righe di un set di risultati alla volta. Allora, la prima recupera le righe da 1 a 20, la seconda le righe da 21 a 40 e così via. Poiché ogni volta che si esegue una query viene creato un nuovo insieme di risultati, l'applicazione client deve assicurarsi che l'insieme dei risultati non cambi tra una query e l'altra. Ad esempio, se dopo aver recuperato le prime 20 righe di un set di risultati come descritto in precedenza, una di queste righe viene eliminata, la riga che sarebbe stata la 21a riga diventa ora la 20a. Per questo motivo, questa riga non viene inclusa quando vengono recuperate le 20 righe successive. Per evitare questo problema, un'applicazione può eseguire tutte le query all'interno di una transazione il cui livello di isolamento è impostato su SNAPSHOT o SERIALIZABLE. Per informazioni sul funzionamento delle transazioni e dei livelli di isolamento in SQL Server, vedere la lezione 16.
ORDER BY order_by_list
OFFSET offset_row_count {ROW IROWS}
[FETCH {FIRST INEXT} fetch_row_count {ROW IROWS} ONLY]
USE AP
GO
SELECT VendorID, InvoiceTotal
FROM Invoices
ORDER BY InvoiceTotal DESC
OFFSET 0 ROWS
FETCH FIRST 5 ROWS ONLY
USE AP
GO
SELECT VendorName, VendorCity, VendorState, VendorZipCode
FROM Vendors
WHERE VendorState = 'CA'
ORDER BY VendorCity
OFFSET 10 ROWS
FETCH NEXT 10 ROWS ONLY
USE AP
GO
CREATE PROCEDURE spShowVendorPerState
@var_state varchar(2),
@var_start int,
@var_range int
AS
BEGIN
SELECT VendorName, VendorCity, VendorState, VendorZipCode
FROM Vendors
WHERE VendorState = @var_state
ORDER BY VendorCity
OFFSET @var_start ROWS
FETCH NEXT @var_range ROWS ONLY
END
USE AP
GO
EXEC spShowVendorPerState
@var_state = N'CA',
@var_start = 10,
@var_range = 5
L'obiettivo di questa lezione è stato quello di insegnare le competenze di base per la codifica di istruzioni SELECT. Queste abilità verranno utilizzate in quasi tutte le istruzioni SELECT che codificherete. Come si vedrà nelle lezioni successive, tuttavia, la codifica delle istruzioni SELECT è molto più di quello che è stato presentato qui. Nelle prossime tre lezioni, quindi, si apprenderanno altre abilità per la codifica delle istruzioni SELECT. Una volta completati queste lezioni, saprete tutto ciò che è necessario sapere per recuperare i dati da un database di SQL Server.