Unterabfragen Subselect (Query auf eine Query)
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
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~