SQL Basis

Hoofdstuk 11 - Subqueries

  • Subqueries zijn queries opgenomen in andere query
  • Subqueries kunnen handig zijn wanneer informatie uit meerdere tabellen nodig is
  • Een subquery kan geplaatst worden in een SELECT, FROM, WHERE of HAVING clausule van een andere query
SELECT <kolom1>, <kolom2>
FROM   <tabel1>
WHERE  <kolom3> IN ( SELECT <kolom4>
                    FROM   <tabel2> 
                    WHERE  <kolom5> IN ( SELECT <kolom6>
                                         FROM   <tabel3>
                                         WHERE  <kolom7> = "Waarde" )); 

  • Elke subquery wordt tussen haakjes gezet
  • Bij de verwerking wordt met de binnensten (rechts) begonnen
  • Het resultaat van een subquery wordt in een door 'komma gescheiden' veld gezet (zoals verplicht bij de IN operator)
  • Het SELECT statement van een subquery mag maar één veld of één kolom bevatten.
  • Test eerst de subquery en dan pas de hoofdquery
  • Knip een complexe vraag in deelproblemen
  • Begin met wat je WEL kunt beantwoorden met een query. Dit wordt meestal de subquery
  • Werk door naar de hoofdvraag. Wat wil je zien/tonen?
  • Schrijf de query zo leesbaar mogelijk

  • Wanneer informatie gefilterd moet worden kan een subquery geplaatst worden in de WHERE
SELECT     <kolom01>,
           <kolom02>
FROM       <tabel01>  
WHERE      <kolom02> IN (
                         SELECT  MAX(kolom03)
                         FROM    <tabel02>
                        );

Geef het product id en de product prijs van het duurste product

TIP

  1. Selecteer de hoogste productprijs uit OrderItems - MAX(item_price) - Subquery
  2. Selecteer prod_id en item_price uit OrderItems - Hoofd query
  3. Filter in de WHERE van de hoofd query; item_price IN (subquery)
  4. Haal de dubbele prod_id's eruit met een DISTINCT
-- Oracle / MySQL / SQL Server
SELECT   prod_id,
         prod_price
FROM     Products  
WHERE    prod_price IN (
                        SELECT MAX(prod_price)
                        FROM Products
                       );
prod_idprod_price
BR0311.99

Selecteer de product id, productnaam en product prijs van de producten die meer kosten dan de gemiddelde productprijs

TIP

  1. Selecteer de gemiddelde productprijs - AVG(prod_price) uit Products - Subquery
  2. Selecteer product id, naam en prijs uit Products - Hoofd query
  3. Filter in de WHERE van de hoofd query; prod_price > subquery
-- Oracle / MySQL / SQL Server
SELECT   prod_id,
         prod_name,
         prod_price
FROM     Products
WHERE    prod_price > ( SELECT AVG(prod_price)
                        FROM Products )
ORDER BY prod_price;
prod_idprod_nameprod_price
BR0212 inch teddy bear8.99
RYL01King doll9.49
RYL02Queen doll9.49
BR0318 inch teddy bear11.99
  • Wanneer 2 tabellen gekoppeld worden is het nodig om een volledig gekwalificeerde kolomnamen te gebruiken
  • Een volledige kolomnaam begint met de tabelnaam gevolgd door een punt en dan de kolomnaam
  • Door volledige kolomnamen te gebruiken kan onderscheid gemaakt worden tussen twee kolommen, met dezelfde naam, uit verschillende tabellen
Products.prod_id 

OrderItems.prod_id
  • Een query die meerdere tabellen aanspreekt wordt het best geschreven met volledige kolomnamen


  • Wanneer informatie getoond moet worden uit verschillende tabellen kan een subquery gebruikt worden in een SELECT
SELECT    <tabel1>.<kolom1>,
          <tabel1>.<kolom2>,
          ( 
            SELECT COUNT(*) 
            FROM   <tabel2>
            WHERE  <tabel2>.<kolom1> = <tabel1>.<kolom1>
          ) AS NieuweKolomNaam
FROM      <tabel1>
ORDER BY  <tabel1>.<kolom1>;

Selecteer de klantnaam en de klant staat(state) en hoeveel bestellingen de klant heeft gedaan

TIP

  1. Selecteer de klantnaam en staat - (Customers)
  2. Hoeveel bestellingen zijn er - ( COUNT(*) From Orders )
  3. Koppel de 2 tabellen in de WHERE van de subquery
-- Oracle / MySQL / SQL Server
SELECT    Customers.cust_name,
          Customers.cust_state,
          ( SELECT COUNT(*)
            FROM   Orders
            WHERE  Orders.cust_id = Customers.cust_id ) AS orders
FROM      Customers
ORDER BY  Customers.cust_name;
cust_namecust_stateorders
Fun4AllIN1
Fun4AllAZ1
Kids PlaceOH0
The Toy StoreIL1
Village ToysMI2
  1. Selecteer de klanten die in dezelfde staat(state) wonen als de leveranciers (2)


  1. Selecteer alle geplaatste Orders waarvan de klant-email niet bekend is (1)


  1. Selecteer de klantnamen van alle geplaatste Orders waarvan de klant-email niet bekend is (1)

TIP

  1. Selecteer uit Customers eerst alle cust_id's waarvan het emailveld leeg is - Sub-sub-query
  2. Selecteer uit Orders alle cust_id's WHERE Orders.cust_id voorkomt IN het resultaat van de vorige stap - sub-query
  3. Selecteer de klantnaam uit Customers WHERE Customers.cust_id voorkomt IN het resultaat van de vorige stap - Hoofd-query


  1. Selecteer alle productnamen uit Products en een extra kolom met het totaal aan verkochte items (9)

TIP

  1. Geef de optelling van quantity uit OrderItems - sum(quantity) - Subquery
  2. Selecteer de productnamen uit Products - Hoofd query
  3. Voeg een WHERE toe aan de subquery waarbij de prod_id uit de 2 tabellen met elkaar worden vergeleken/gelijkgesteld ( ... = ... )
  4. Geef de nieuwe kolom een passende naam


  1. Selecteer de klant id's en per order het totaalbedrag van wat ze besteld hebben (5)

TIP

  1. Selecteer de optelling van quantity * item_price uit orderItems - Subquery
  2. Selecteer het cust_id uit Orders - Hoofd query
  3. Voeg een WHERE toe aan de subquery waarbij de order_num uit de 2 tabellen met elkaar worden vergeleken/gelijkgesteld ( ... = ... )
  4. Geef de nieuwe kollom een passende naam