Filtrare i dati con predicati

Completato

Le istruzioni SELECT più semplici con solo clausole SELECT e FROM valuteranno ogni riga di una tabella. Usando una clausola WHERE si definiscono le condizioni che determinano quali righe verranno elaborate e che potrebbero ridurre il set di risultati.

Struttura della clausola WHERE

La clausola WHERE è costituita da una o più condizioni di ricerca, ognuna delle quali deve restituire TRUE, FALSE o 'unknown' per ogni riga della tabella. Le righe verranno restituite solo quando la clausola WHERE restituisce TRUE. Le singole condizioni fungono da filtri sui dati e sono note come 'predicati'. Ogni predicato include una condizione che viene verificata, in genere tramite gli operatori di confronto di base:

  • = (uguale a)
  • <> (non uguale a)
  • > (maggiore di)
  • >= (maggiore o uguale a)
  • < (minore di)
  • <= (minore o uguale a)

Ad esempio, la query seguente restituisce tutti i prodotti con un valore ProductCategoryID pari a 2:

SELECT ProductCategoryID AS Category, ProductName
FROM Production.Product
WHERE ProductCategoryID = 2;

Analogamente, la query seguente restituisce tutti i prodotti con valore di ListPrice minore di 10.00:

SELECT ProductCategoryID AS Category, ProductName
FROM Production.Product
WHERE ListPrice < 10.00;

IS NULL / IS NOT NULL

È anche possibile filtrare facilmente per consentire o escludere i valori 'unknown' o NULL usando IS NULL o IS NOT NULL.

SELECT ProductCategoryID AS Category, ProductName
FROM Production.Product
WHERE ProductName IS NOT NULL;

Più condizioni

È possibile combinare più predicati con gli operatori AND e OR e con parentesi. Tuttavia, SQL Server elabora solo due condizioni alla volta. Tutte le condizioni devono essere TRUE quando si connettono più condizioni con l'operatore AND. Quando si usa l'operatore OR per connettere due condizioni, una o entrambe possono essere TRUE per il set di risultati.

Ad esempio, la query seguente restituisce il prodotto nella categoria 2 che costa meno di 10.00:

SELECT ProductCategoryID AS Category, ProductName
FROM Production.Product
WHERE ProductCategoryID = 2
    AND ListPrice < 10.00;

Gli operatori AND vengono elaborati prima degli operatori OR, a meno che non vengano usate le parentesi. La procedura consigliata prevede l'uso delle parentesi quando si usano più di due predicati. La query seguente restituisce i prodotti nella categoria 2 OR 3 AND costa meno di 10,00:

SELECT ProductCategoryID AS Category, ProductName
FROM Production.Product
WHERE (ProductCategoryID = 2 OR ProductCategoryID = 3)
    AND (ListPrice < 10.00);

Operatori di confronto

Transact-SQL include operatori di confronto utili per semplificare la clausola WHERE.

IN

L'operatore IN è un collegamento per più condizioni di uguaglianza per la stessa colonna connessa con OR. Non c'è nulla di sbagliato nell'usare più condizioni OR in una query, come nell'esempio seguente:

SELECT ProductCategoryID AS Category, ProductName
FROM Production.Product
WHERE ProductCategoryID = 2
    OR ProductCategoryID = 3
    OR ProductCategoryID = 4;

Tuttavia, l'uso di IN è chiaro e conciso e non ci saranno effetti negativi sulle prestazioni della query.

SELECT ProductCategoryID AS Category, ProductName
FROM Production.Product
WHERE ProductCategoryID IN (2, 3, 4);

BETWEEN

BETWEEN è un'altra scorciatoia che può essere usata per filtrare i dati in base a un limite superiore e inferiore per il valore, invece di usare due condizioni con l'operatore AND. Le due query seguenti sono equivalenti:

SELECT ProductCategoryID AS Category, ProductName
FROM Production.Product
WHERE ListPrice >= 1.00
    AND ListPrice <= 10.00;
SELECT ProductCategoryID AS Category, ProductName
FROM Production.Product
WHERE ListPrice BETWEEN 1.00 AND 10.00;

L'operatore BETWEEN usa valori limite inclusivi. I prodotti con un prezzo di 1.00 o 10.00 verranno inclusi nei risultati. BETWEEN è utile anche per l'esecuzione di query sui campi di data. Ad esempio, la query seguente includerà tutti i nomi dei prodotti modificati tra il 1° gennaio 2012 e il 31 dicembre 2012:

SELECT ProductName, ModifiedDate
FROM Production.Product
WHERE ModifiedDate BETWEEN '2012-01-01' AND '2012-12-31';

ProductName

ModifiedDate

Calzini da mountain bike, M

2012-01-01 00:00:00.000

HL Mountain Frame - argento, 42

2012-03-05 00:00:00.000

HL Mountain Frame - argento, 38

2012-08-29 00:00:00.000

Mountain-100 argento, 38

2012-12-31 00:00:00.000

Tuttavia, poiché non si specifica un intervallo di tempo, non vengono restituiti risultati dopo il 2012-12-31 00:00:00.000. Per includere in modo accurato data e ora, è necessario includere l'ora nel predicato:

SELECT ProductName, ListPrice, ModifiedDate
FROM Production.Product
WHERE ModifiedDate BETWEEN '2012-01-01 00:00:00.000' AND '2012-12-31 23:59:59.999';

Anche gli operatori di confronto di base, ad esempio maggiore di (>) e uguale a (=) sono accurati quando si filtrano i dati solo in base alla data:

SELECT ProductName, ListPrice, ModifiedDate
FROM Production.Product
WHERE ModifiedDate >= '2012-01-01' 
    AND ModifiedDate < '2013-01-01';

LIKE

L'operatore di confronto finale può essere usato solo per i dati di tipo carattere e consente di usare caratteri jolly e modelli di espressione regolare. I caratteri jolly consentono di specificare stringhe parziali. Ad esempio, è possibile usare la query seguente per restituire tutti i prodotti con nomi che contengono la parola "mountain":

SELECT Name, ListPrice
FROM SalesLT.Product
WHERE Name LIKE '%mountain%';

Il carattere jolly %rappresenta qualsiasi stringa di 0 o più caratteri, pertanto i risultati includono i prodotti con la parola "mountain" in qualsiasi punto del nome, come nell'esempio seguente:

Name

ListPrice

Calzini da mountain bike, M

9.50

Mountain Bike Socks, L

9.50

HL Mountain Frame - argento, 42

1364.0

HL Mountain Frame - argento, 42

1349.60

HL Mountain Frame - argento, 38

1364.50

Mountain-100 argento, 38

3399.99

È possibile usare il carattere jolly _ (sottolineatura) per rappresentare un unico carattere, come nell'esempio seguente:

SELECT ProductName, ListPrice
FROM SalesLT.Product
WHERE ProductName LIKE 'Mountain Bike Socks, _';

I risultati seguenti includono solo i prodotti che iniziano con "Mountain Bike Socks, " e un singolo carattere dopo:

ProductName

ListPrice

Calzini da mountain bike, M

9.50

Mountain Bike Socks, L

9.50

È anche possibile definire modelli complessi per le stringhe da trovare. Ad esempio, la query seguente cerca i prodotti con un nome che inizia con "Mountain-", seguito da:

  • tre caratteri compresi tra 0 e 9
  • uno spazio
  • qualsiasi stringa
  • una virgola
  • uno spazio
  • due caratteri compresi tra 0 e 9
SELECT ProductName, ListPrice
FROM SalesLT.Product
WHERE ProductName LIKE 'Mountain-[0-9][0-9][0-9] %, [0-9][0-9]';

I risultati di questa query potrebbero essere simili ai seguenti:

ProductName

ListPrice

Mountain-100 argento, 38

3399.99

Mountain-100 Silver, 42

3399.99

Mountain-100 nero, 38

3399.99

Mountain-100 nero, 42

3399.99

Mountain-200 argento, 38

2319.99

Mountain-200 argento, 42

2319.99

Mountain-200 nero, 38

2319.99

Mountain-200 nero, 42

2319.99