SQL: Max-Wert tabellenübergreifend ermitteln
BlueFish
- datenbank
Hallo nochmal,
jetzt ist noch eine zweite Frage aufgetaucht, bei der ich nicht auf eine Lösung komme: Angenomme, ich habe eine Datenbank mit mehreren Produkttabellen, zB. eine Tabelle PC, eine Tabelle Laptop usw. Jede dieser Tabellen hat auch ein Attribut Preis. Nun möchte ich das Produkt (egal ob es sich um einen Laptop oder PC etc. handelt) mit dem höchsten Preis ermitteln.
Grundsätzlich kann ich ja mit max(Preis) den höchsten Preis aus der jeweiligen Tabelle abfragen und damit auch das zugehörige Produkt. Aber wie komme ich zu dem Produkt mit dem höchsten Preis aus allen Tabellen? Ich kann ja kein max(Preis) auf eine Ergebnisrelation mit den maximalen Preisen aller Produktgruppen anwenden, irgendwie komme ich da auf keine durchführbare Idee.
Grüße
BlueFish
Hallo
jetzt ist noch eine zweite Frage aufgetaucht, bei der ich nicht auf eine Lösung komme: Angenomme, ich habe eine Datenbank mit mehreren Produkttabellen, zB. eine Tabelle PC, eine Tabelle Laptop usw. Jede dieser Tabellen hat auch ein Attribut Preis.
das sieht nach einer miserablen Datenmodellierung aus :-)
Korrigiere diese - und das Problem erledigt sich von selbst.
Nun möchte ich das Produkt (egal ob es sich um einen Laptop oder PC etc. handelt) mit dem höchsten Preis ermitteln.
Grundsätzlich kann ich ja mit max(Preis) den höchsten Preis aus der jeweiligen Tabelle abfragen und damit auch das zugehörige Produkt. Aber wie komme ich zu dem Produkt mit dem höchsten Preis aus allen Tabellen? Ich kann ja kein max(Preis) auf eine Ergebnisrelation mit den maximalen Preisen aller Produktgruppen anwenden, irgendwie komme ich da auf keine durchführbare Idee.
UNION (ALL) hilft Dir weiter.
Die Details sind möglicherweise mal wieder ein Fall für die beliebten
korrelierten Subselects, siehe dieses Archivposting von mir.
Freundliche Grüße
Vinzenz
Hallo,
das sieht nach einer miserablen Datenmodellierung aus :-)
Korrigiere diese - und das Problem erledigt sich von selbst.
Hehe, ja, das hab ich mir auch gedacht ... wie kann man sowas überhaupt zusammenbringen. Aber nunja, ich bin dabei für eine Klausur zu lernen und habe hier eine Übung, wo so ein Bsp vorkommt. Allerdings ohne Lösung.
UNION (ALL) hilft Dir weiter.
Ja, an UNION habe ich ebenfalls schon gedacht. Da kann ich eine schöne Ergebnisrelation machen wo genau alle meine max-Werte drinstehn. Und wie krieg ich dann noch aus den max-Werten den max-Wert? Genau da hakt es, ich weiß nicht wie ich da weiterkommen soll. Ich bräuchte irgendwie noch ein übergeordnetes SELECT max aber wie ich das zusammenbauen kann sodass das dann rauskommt ...?
Grüße
BlueFish
Hallo,
Ja, an UNION habe ich ebenfalls schon gedacht. Da kann ich eine schöne Ergebnisrelation machen wo genau alle meine max-Werte drinstehn. Und wie krieg ich dann noch aus den max-Werten den max-Wert? Genau da hakt es, ich weiß nicht wie ich da weiterkommen soll. Ich bräuchte irgendwie noch ein übergeordnetes SELECT max aber wie ich das zusammenbauen kann sodass das dann rauskommt ...?
Im Zweifel kannst du dir immer einen VIEW oder TEMPORARY TABLE erzeugen. Falls du ein Bespiel nicht mit einer "magic query" Lösen kannst, versuche es auf mehere Queries zu verteilen (Du kannst sie mit ; trennen).
Gruß,
Severin
Hallo
UNION (ALL) hilft Dir weiter.
Ja, an UNION habe ich ebenfalls schon gedacht. Da kann ich eine schöne Ergebnisrelation machen wo genau alle meine max-Werte drinstehn. Und wie krieg ich dann noch aus den max-Werten den max-Wert? Genau da hakt es, ich weiß nicht wie ich da weiterkommen soll. Ich bräuchte irgendwie noch ein übergeordnetes SELECT max aber wie ich das zusammenbauen kann sodass das dann rauskommt ...?
Mit einem Subselect, wobei Du der Ergebnismenge des Subselects einen Namen gibst:
SELECT
MAX(tmp.feldname)
FROM (
SELECT
t1.feldname,
[...]
FROM tabelle1 t1
UNION ALL
t2.feldname,
[...]
FROM tabelle2 t2
[...]
) AS tmp
Freundliche Grüße
Vinzenz
Hallo!
Hmm, also mit Deinem Vorschlag mit dem SELECT AS tmp bin ich jetzt zwar zu einer Lösung gekommen, aber dass man das so machen sollte, glaube ich wieder weniger ... das ist ja grauenhaft:
SELECT distinct pc.model as model FROM pc WHERE pc.price >= (
SELECT MAX(tmp.price) FROM (
SELECT pc.price, pc.model FROM pc
UNION ALL
SELECT laptop.price, laptop.model FROM laptop
UNION ALL
SELECT printer.price, printer.model FROM printer
) AS tmp
)
UNION ALL
SELECT distinct laptop.model as model FROM laptop WHERE laptop.price >= (
SELECT MAX(tmp.price) FROM (
SELECT pc.price, pc.model FROM pc
UNION ALL
SELECT laptop.price, laptop.model FROM laptop
UNION ALL
SELECT printer.price, printer.model FROM printer
) AS tmp
)
UNION ALL
SELECT distinct printer.model as model FROM printer WHERE printer.price >= (
SELECT MAX(tmp.price) FROM (
SELECT pc.price, pc.model FROM pc
UNION ALL
SELECT laptop.price, laptop.model FROM laptop
UNION ALL
SELECT printer.price, printer.model FROM printer
) AS tmp
)
Es kommt zwar mit meinen Testdaten das Richtige heraus ... aber ich glaub', ich vergess das mal lieber ganz schnell wieder.
Grüße
BlueFish
Hallo,
Grundsätzlich kann ich ja mit max(Preis) den höchsten Preis aus der jeweiligen Tabelle abfragen und damit auch das zugehörige Produkt. Aber wie komme ich zu dem Produkt mit dem höchsten Preis aus allen Tabellen?
Dafür eignet sich greatest():
SELECT GREATEST(
(SELECT MAX(price)FROM pc)
,
(SELECT MAX(price)FROM laptop)
)
Gruß,
Severin
Hallo
Dafür eignet sich greatest():
wenn es diese Funktion gibt. Bei mir gibt es nur einen Syntaxfehler :-)
Freundliche Grüße
Vinzenz
Hallo,
wenn es diese Funktion gibt. Bei mir gibt es nur einen Syntaxfehler :-)
Welches DBMS?
Gruß,
Severin
Hallo
wenn es diese Funktion gibt. Bei mir gibt es nur einen Syntaxfehler :-)
Welches DBMS?
SQL-Standard :-)
Freundliche Grüße
Vinzenz
Hallo,
SQL-Standard :-)
Gah ;-) Es ist zwar nicht im Standard, wird dafür aber von vielen DBMS unterstützt (auf jeden Fall: Oracle, MSSQL, MySQL und PostgreSQL). Da es hier um Klausur-/Hausaufgaben geht ist für mich die einfachste/kürzeste Lösung die beste.
Gruß,
Severin
Hallo!
Stimmt, mit GREATEST hats hier auch funktioniert - teste auf MySQL. Wieder was gelernt, danke, kannte ich gar nicht! Bei der Klausur wird das DBMS ohnehin nicht vorgegeben sein, ich könnte es also sogar verwenden!
Aber den Rest meiner Abfrage (ich soll ja den Namen des Produkts ausgeben, nicht den Preis) habe ich trotzdem ziemlich stümperhaft zusammengepfriemelt :-(
Grüße
BlueFish
Hallo
Stimmt, mit GREATEST hats hier auch funktioniert - teste auf MySQL. Wieder was gelernt, danke, kannte ich gar nicht! Bei der Klausur wird das DBMS ohnehin nicht vorgegeben sein, ich könnte es also sogar verwenden!
... und es könnte Dir aus genanntem Grund als Fehler angerechnet werden :-)
Aber den Rest meiner Abfrage (ich soll ja den Namen des Produkts ausgeben, nicht den Preis) habe ich trotzdem ziemlich stümperhaft zusammengepfriemelt :-(
kannst Du was für kaputtes Tabellendesign in der Aufgabe?
Freundliche Grüße
Vinzenz
Hello again,
... und es könnte Dir aus genanntem Grund als Fehler angerechnet werden :-)
Stimmt auch wieder - hoffe ich aber nicht. Ganz im allgemeinen hoffe ich überhaupt, dass so ein komisches Beispiel nicht kommt, aber mangels SQL-Beispielen in unseren eigenen Übungen musste ich mir eben irgendwas von anderen Unis zusammensuchen um ein bisschen üben zu können.
Aber den Rest meiner Abfrage (ich soll ja den Namen des Produkts ausgeben, nicht den Preis) habe ich trotzdem ziemlich stümperhaft zusammengepfriemelt :-(
kannst Du was für kaputtes Tabellendesign in der Aufgabe?
Da hast Du auch wieder recht. Man könnte es zwar sicherlich auch irgendwie "schöner" lösen, aber die Aufgabe an sich ist ja schon "hässlich", also lass ich das jetzt wohl auch gut sein und mach mich wieder ans Weiterlernen.
Schönen Dank für Eure Hilfe!
BlueFish
Hallo,
kannst Du was für kaputtes Tabellendesign in der Aufgabe?
hehe - dem Professor beweisen, dass das Design nicht in Boyce-Codd-Normalform ist ;-)
Stimmt auch wieder - hoffe ich aber nicht. Ganz im allgemeinen hoffe ich überhaupt, dass so ein komisches Beispiel nicht kommt, aber mangels SQL-Beispielen in unseren eigenen Übungen musste ich mir eben irgendwas von anderen Unis zusammensuchen um ein bisschen üben zu können.
Ich glaube ich habe aus meinem DB Kurs noch alte Musterklausuren (aber wohl nur ohne Lösung). Falls du sie brauchst, schreib mir einfach ein E-Mail.
Gruß,
Severin
Hi,
kannst Du was für kaputtes Tabellendesign in der Aufgabe?
hehe - dem Professor beweisen, dass das Design nicht in Boyce-Codd-Normalform ist ;-)
Hm, das war zwar nicht die ursprüngliche Frage, aber wie sollte man das beweisen? Es gibt 3 Relationen, jede Relation hat einen Primärschlüssel (id), einen Produktnamen (model), einen preis (price) und gegebenenfalls noch weitere Attribute (hd, ram, screen usw.). Insofern sollte jede Relation für sich jedenfalls durchaus in BCNF sein, es gibt ja nichtmal einen zusammengesetzten Schlüssel, somit können ja auch kaum FDs unter Schlüsselattributen bestehen!? Versteh ich nicht ...
Grüße
BlueFish
Hallo,
Hm, das war zwar nicht die ursprüngliche Frage, aber wie sollte man das beweisen?
Es war nicht wirklich ernst gemeint. Ich glaube ein "dummes" Schema sollte wohl auffallen, wenn man es in eine der hohen Normalformen bringt - aber es ist bei mir leider schon wieder zu lang her.
Gruß,
Severin
PS: E-Mail ist raus, es ist aber relativ groß - sag bescheid falls es nicht angekommen ist.
Hi,
Hm, das war zwar nicht die ursprüngliche Frage, aber wie sollte man das beweisen?
Es war nicht wirklich ernst gemeint. Ich glaube ein "dummes" Schema sollte wohl auffallen, wenn man es in eine der hohen Normalformen bringt - aber es ist bei mir leider schon wieder zu lang her.
Aah! Ok! Ich dachte schon ... ;-)
Die Normalformen (kenne nur 1 - 3 und BCNF) kümmern sich ja eigentlich alle (ausgenommen die erste) "nur" um funktionale Abhängigkeiten, und die sind hier ja innerhalb der einzelnen Relationen betrachtet wohl ok, so gesehen ... wie auch immer, das Beispiel ist doof.
PS: E-Mail ist raus, es ist aber relativ groß - sag bescheid falls es nicht angekommen ist.
Ist angekommen - dankeschön!
Grüße
BlueFish