BlueFish: SQL: Max-Wert tabellenübergreifend ermitteln

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

  1. 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

    1. 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

      1. 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

        --
        They that can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.
        -- Benjamin Franklin
      2. 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

        1. 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

  2. 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

    --
    They that can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.
    -- Benjamin Franklin
    1. Hallo

      Dafür eignet sich greatest():

      wenn es diese Funktion gibt. Bei mir gibt es nur einen Syntaxfehler :-)

      Freundliche Grüße

      Vinzenz

      1. Hallo,

        wenn es diese Funktion gibt. Bei mir gibt es nur einen Syntaxfehler :-)

        Welches DBMS?

        Gruß,
        Severin

        --
        They that can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.
        -- Benjamin Franklin
        1. Hallo

          wenn es diese Funktion gibt. Bei mir gibt es nur einen Syntaxfehler :-)

          Welches DBMS?

          SQL-Standard :-)

          Freundliche Grüße

          Vinzenz

          1. 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

            --
            They that can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.
            -- Benjamin Franklin
            1. 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

              1. 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

                1. 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

                  1. 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

                    --
                    They that can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.
                    -- Benjamin Franklin
                    1. 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

                      1. 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.

                        --
                        They that can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.
                        -- Benjamin Franklin
                        1. 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