Usare clausole HAVING e WHERE nella stessa query (Visual Database Tools)

Si applica a:SQL Serverdatabase SQL di AzureIstanza gestita di SQL di AzureAzure Synapse AnalyticsPiattaforma di strumenti analitici (PDW)

In alcuni casi può essere necessario escludere singole righe dai gruppi (usando una clausola WHERE) prima di applicare una condizione ai gruppi nel loro complesso (usando una clausola HAVING).

La clausola HAVING è analoga alla clausola WHERE ma è applicabile solo ai gruppi come insieme, ossia alle righe nel set di risultati che rappresentano i gruppi, mentre la clausola WHERE è applicabile a righe singole. Una query può contenere sia una clausola WHERE che una clausola HAVING. In questo caso:

  • La clausola WHERE viene applicata prima alle singole righe nelle tabelle o negli oggetti con valori di tabella nel riquadro Diagramma. Vengono raggruppate solo le righe che soddisfano le condizioni della clausola WHERE.

  • Successivamente viene applicata la clausola HAVING alle righe del set di risultati. Nell'output della query saranno visualizzati solo i gruppi che soddisfano le condizioni HAVING. La clausola HAVING può essere applicata solo alle colonne presenti anche nella clausola GROUP BY o in una funzione di aggregazione.

Specificare una clausola WHERE e una HAVING in due tabelle unite

Nota

Il database usato in questo articolo è il database pubs, disponibile nei database di esempio Northwind e pubs per Microsoft SQL Server su GitHub.

Si supponga ad esempio di unire le tabelle titles e publishers per creare una query in cui sia visualizzato il prezzo medio dei libri per un set di editori, limitando la ricerca a un set specifico di editori, ad esempio quelli dello stato della California. E anche in questo caso, a un prezzo medio maggiore di 10 dollari.

In questo caso, prima di calcolare il prezzo medio è possibile stabilire la prima condizione con una clausola WHERE che escluda tutti gli editori che non si trovano in California. La seconda condizione richiede una clausola HAVING, in quanto la condizione è basata sui risultati del raggruppamento e del riepilogo di dati. L'istruzione SQL risultante sarà analoga alla seguente:

SELECT titles.pub_id, AVG(titles.price)
FROM titles INNER JOIN publishers
   ON titles.pub_id = publishers.pub_id
WHERE publishers.state = 'CA'
GROUP BY titles.pub_id
HAVING AVG(price) > 10;

In Visual Database Tools di SQL Server Management Studio è possibile creare clausole HAVING e WHERE nel riquadro Criteri. In base all'impostazione predefinita, se si specifica una condizione di ricerca per una colonna, tale condizione entrerà a far parte della clausola HAVING. Tuttavia, è comunque possibile cambiare la condizione in una clausola WHERE.

È possibile creare una clausola WHERE e una clausola HAVING relative alla stessa colonna. A tale scopo, è necessario aggiungere due volte la colonna nel riquadro Criteri, quindi assegnare un'istanza alla clausola HAVING e l'altra alla clausola WHERE.

Specificare una condizione WHERE in una query di aggregazione

  1. Specificare i gruppi per la query. Per informazioni dettagliate, vedere Raggruppare righe nei risultati di una query (Visual Database Tools).

  2. Se necessario, aggiungere nel riquadro Criteri la colonna su cui si vuole basare la condizione WHERE.

  3. Se la colonna di dati non è inclusa nella clausola GROUP BY o nella funzione di aggregazione, eliminare il contenuto della colonna Output .

  4. Nella colonna Filtro specificare la condizione WHERE. La condizione verrà aggiunta alla clausola HAVING dell'istruzione SQL.

    Nota

    Nella query illustrata nell'esempio della procedura vengono unite due tabelle: titles e publishers.

    A questo punto della creazione della query, l'istruzione SQL contiene una clausola HAVING:

    SELECT titles.pub_id, AVG(titles.price)
    FROM titles INNER JOIN publishers
        ON titles.pub_id = publishers.pub_id
    GROUP BY titles.pub_id
    HAVING publishers.state = 'CA'
    
  5. Selezionare Where dall'elenco di opzioni di raggruppamento e riepilogo nella colonna Group By . La condizione verrà rimossa dalla clausola HAVING dell'istruzione SQL e aggiunta alla clausola WHERE.

    L'istruzione SQL includerà ora una clausola WHERE:

    SELECT titles.pub_id, AVG(titles.price)
    FROM titles INNER JOIN publishers
        ON titles.pub_id = publishers.pub_id
    WHERE publishers.state = 'CA'
    GROUP BY titles.pub_id;