Unterabfragen Subselect (Query auf eine Query)

edit | delete

Autor: Vilma Plum

eingetragen: Mittwoch, 19. Dezember 2007 um 11:49 Uhr (51/2007 Kalenderwoche)

geändert: Donnerstag, 28. April 2011 um 14:24 Uhr (17/2011 Kalenderwoche)

Keywords: unterabfragen subselect select Query From subqueries subquery

Kategorien: DB: MySQL, DB: PostgreSQL, DB: MariaDB,

Text:

Unterabfragen sind immer dann relevant, wenn zunächst ein Maximalwert einer Spalte ermittelt werden muss. (z. B.:nur das aktuellste Datum soll angezeigt werden).
Diese Unterabfragen können in der Tabellen-Listung gemacht werden, aber auch in der WHERE-Bedingung (Zeilenunterabfrage).
Das folgende Beiospiel zeigt eine Zeilenunterabfrage (Datumsberechnung hier allerdings in Postgres). Die Syntax ist dem MySQL-Handbuch entnommen, funktioniert aber auch in Postgres.
Ein Vergleich der Laufzeiten ergab, dass die Zeilenunterabfrage ca. 20% schneller war.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Ergänzung: 2. und 3. Query ist nicht in Postgres getestet, aber im MySQL.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
http://dev.mysql.com/doc/refman/5.1/de/subqueries.html
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Quellcode:  

SELECT price_id, price, market_id, product_id, market_date
FROM   price
WHERE (market_id, product_id, trade_class_id, market_date) IN (
         SELECT   market_id, product_id, MAX(market_date) AS market_date 
         FROM     price  
         WHERE    trade_class_id = 3
         AND      market_date > CURRENT_DATE -integer '90'
         GROUP BY market_id, product_id, trade_class_id
       )
 ORDER BY market_id, product_id, trade_class_id ASC

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

SELECT   t.id, t.bereich, t.titel, t.jahr, count( t.id ) AS anz
FROM     ext_dbstatmon_main m, ext_dbstatmon_stichwort s, (

       SELECT t3.*
       FROM   (

               SELECT   t2.*
               FROM     ext_dbstatmon_tabelle t2
               WHERE    t2.jahr = 2008
               ORDER BY t2.jahr ASC
       ) t3
       WHERE    t3.jahr = 2008
       GROUP BY t3.bereich
    
    ) t
WHERE    m.id_tabnr = t.id
AND      m.id_stichwort = s.id
GROUP BY t.id, t.tabnr
ORDER BY t.bereich ASC, anz DESC

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

SELECT count(s.einrchtg_id) AS auftrags_anzahl,
       s.einrchtg_id, s.einrchtg_name_de, s.einrchtg_akronym
FROM (
      SELECT f.einrchtg_id AS einrchtg_id,
             f.einrchtg_name_de AS einrchtg_name_de,
             f.einrchtg_akronym AS einrchtg_akronym,
             a.auftrags_id AS auftrags_id
        FROM bmelv_ais.ais_mitwirk_einrtg AS v,
             bmelv_ais.ais_auftraege AS a,
             bmelv_ipa.ipa_einrichtg AS f
        Where v.ipa_ober_einrchtg_id = f.einrchtg_id
        AND   v.auftrags_id = a.auftrags_id
        AND   f.einrchtg_parent_id = 2
        AND   a.auftrags_status IN (3,4,5,6)
        GROUP BY a.auftrags_id
) AS s
GROUP BY s.einrchtg_id
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~