Ankündigung

Einklappen
Keine Ankündigung bisher.

Ein größter Wert aus zwei Tabellen

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Ein größter Wert aus zwei Tabellen

    Hi, habe eine kleine Anfrage zwecks einem SQL SELECT in zwei Tables zur Ausgabe eines(!) größten Wertes.

    Zwei verschiedene Tables in einer DB mit einer gleichen Column. Es handelt sich um eine Datenbank von einem Photo-CMS. Die ganze Sache ist in Baumstruktur angelegt, wie in einem Dateiverzeichnis. Das CMS und das DB Design ist nicht von mir.

    Code:
    [id - name - parentid/albumid]
    0 - Foto-Ordner -
    - 1 - Meine-Fotos - 0
    - 8 - PHOTO018.JPG - 0
    - 9 - PHOTO019.JPG - 0
    -- 3 - Privat-Fotos - 1
    --- 0 - PHOTO010.JPG - 3
    --- 1 - PHOTO011.JPG - 3
    --- 2 - PHOTO012.JPG - 3
    --- 3 - PHOTO013.JPG - 3
    -- 4 - Urlaub-Fotos - 1
    --- 4 - PHOTO014.JPG - 4
    --- 5 - PHOTO015.JPG - 4
    --- 6 - PHOTO016.JPG - 4
    --- 7 - PHOTO017.JPG - 4
    --- 5 - FRÜHLING - 4
    --- 6 - SOMMER - 4
    --- 7 - HERBST - 4
    --- 8 - WINTER - 4
    
    albums
    ########################
    #id#parentid#sort_order#
    ########################
    #5 #4       #0         #
    #6 #4       #6         #
    #7 #4       #5         #
    #8 #4       #7         #
    ########################
    
    images
    #######################
    #id#albumid#sort_order#
    #######################
    #4 #4      #2         #
    #5 #4      #4         #
    #6 #4      #3         #
    #7 #4      #1         #
    #######################
    
    Sortierung:
    FRÜHLING
    PHOTO017.JPG
    PHOTO014.JPG
    PHOTO016.JPG
    PHOTO015.JPG
    HERBST
    SOMMER
    WINTER
    Die Werte in "sort_order" in beiden Tables sind abhängig voneinander. Es kommen also keine gleichen Werte in der Column "sort_order" je Verknüpfung vor (Verknüpfung: albums.parentid=images.albumid).

    Es soll per SQL SELECT der (ein!) größte Wert aus den gleichen COLUMS der beiden Tables abgefragt werden. Bisher bekomme ich nur die größten Werte je Table, also zwei größte Werte, eben die aus jeder Table.

    Code:
    SELECT `albums`.`parentid`, `images`.`albumid`,
    MAX(`albums`.`sort_order`) AS 'albumssortorder',
    MAX(`images`.`sort_order`) AS 'imagessortorder'
    FROM `albums`, `images`
    WHERE `albums`.`parentid`='" . $parent_id . "'
    AND `images`.`albumid`='" . $album_id . "'
    Damit bekomme ich zwei MAX-Werte in einem Array.
    $result['albumssortorder'] // 7
    $result['imagessortorder'] // 4

    Ich suche nach einem SQL SELECT mit dem result = 7, ohne dass eine der beiden Tables ignoriert wird, weil es auch vorkommt, dass der größte Wert in "images" steht.

    Ist es möglich schon im SQL SELECT nur den größeren der beiden Werte auszugeben?


  • #2
    Dein SQL ist falsch, weil bei Aggregationen (max ist eine Aggregation) alle Spalten im Result entweder aggregiert oder gruppiert werden müssen. MySQL erkennt das nicht und liefert ein Zufallsresultat. Weiterhin fehlt eine JOIN-Condition, was zu einen cross join führen dürfte.
    Was Du suchst ist ein UNION zweiter Ergebnissmengen und darauf noch mal ein max().
    PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

    Kommentar


    • #3
      Code:
      SELECT
          GREATEST(MAX(a.sort_order), MAX(i.sort_order))
      FROM
          albums a
      INNER JOIN
          images i ON ( i.albumid = a.parentid )
      WHERE
          i.albumid = 4
      Code:
      mysql> CREATE TABLE albums (
          ->   id int(11) NOT NULL,
          ->   parentid int(11) NOT NULL,
          ->   sort_order int(11) NOT NULL
          -> ) ENGINE=InnoDB;
      Query OK, 0 rows affected (0.04 sec)
      
      mysql> INSERT INTO albums (id, parentid, sort_order) VALUES
          -> (5, 4, 0),
          -> (6, 4, 6),
          -> (7, 4, 5),
          -> (8, 4, 7);
      Query OK, 4 rows affected (0.00 sec)
      Records: 4  Duplicates: 0  Warnings: 0
      
      mysql> CREATE TABLE images (
          ->   id int(11) NOT NULL,
          ->   albumid int(11) NOT NULL,
          ->   sort_order int(11) NOT NULL
          -> ) ENGINE=InnoDB;
      Query OK, 0 rows affected (0.03 sec)
      
      mysql> INSERT INTO images (id, albumid, sort_order) VALUES
          -> (4, 4, 2),
          -> (5, 4, 4),
          -> (6, 4, 3),
          -> (7, 4, 1);
      Query OK, 4 rows affected (0.00 sec)
      Records: 4  Duplicates: 0  Warnings: 0
      
      mysql> SELECT
          ->     GREATEST(MAX(a.sort_order), MAX(i.sort_order))
          -> FROM
          ->     albums a
          -> INNER JOIN
          ->     images i ON ( i.albumid = a.parentid )
          -> WHERE
          ->     i.albumid = 4;
      +------------------------------------------------+
      | GREATEST(MAX(a.sort_order), MAX(i.sort_order)) |
      +------------------------------------------------+
      |                                              7 |
      +------------------------------------------------+
      1 row in set (0.00 sec)

      Kommentar


      • #4
        Danke Hellbringer. Ich hab deines jetzt mal nicht ausprobiert, sondern erstmal die Hinweise von:
        Zitat von akretschmer Beitrag anzeigen
        Was Du suchst ist ein UNION zweiter Ergebnissmengen und darauf noch mal ein max().
        Also https://www.w3schools.com/sql/sql_union.asp
        Ich habe mal ein UNION ALL genommen, falls wenn es doch doppelte Zahlen in beiden Tabellen-Cols geben sollte.
        Code:
        SELECT `albums`.`parentid`, `albums`.`sort_order`
        FROM `albums`
        WHERE `albums`.`parentid`='" . $parent_id . "'
        UNION ALL
        SELECT `images`.`albumid`, `images`.`sort_order`
        FROM `images`
        WHERE `images`.`albumid`='" . $album_id . "'
        FRAGE: Wo soll das MAX hin?
        FRAGE: Was passiert, wenn es zwei gleiche größte Zahlen gibt?

        Kommentar


        • #5
          Per SubQuery vielleicht? Ist das valide und auch effizient bezüglich Performance?
          Code:
          SELECT MAX(sort_order) AS 'MAXSORTORDER'
          FROM (
          SELECT `albums`.`parentid`, `albums`.`sort_order`
          FROM `albums`
          WHERE `albums`.`parentid`='" . $parent_id . "'
          UNION ALL
          SELECT `images`.`albumid`, `images`.`sort_order`
          FROM `images`
          WHERE `images`.`albumid`='" . $album_id . "'
          ) as subquery
          
          $result["MAXSORTORDER"];

          Kommentar


          • #6
            Warum nimmst du nicht das funktionierende Beispiel von hellbringer?

            Kommentar


            • #7
              Wär wohl zu einfach.

              Kommentar


              • #8
                Zitat von psoido Beitrag anzeigen
                FRAGE: Wo soll das MAX hin?
                FRAGE: Was passiert, wenn es zwei gleiche größte Zahlen gibt?
                Code:
                test=# create table a(i) as select random()*100 from generate_series(1,20) a;
                SELECT 20
                test=*# create table b(i) as select random()*100 from generate_series(1,20) b;
                SELECT 20
                
                test=*# select min(m) from (select min(i) as m from a union all select min(i) from b) x;
                       min        
                ------------------
                 3.40780504047871
                (1 row)
                PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

                Kommentar


                • #9
                  Zitat von psoido Beitrag anzeigen
                  FRAGE: Was passiert, wenn es zwei gleiche größte Zahlen gibt?
                  Probier es doch aus, dann weisst du es.
                  Code:
                  mysql> SELECT GREATEST (4,4);
                  +----------------+
                  | GREATEST (4,4) |
                  +----------------+
                  |              4 |
                  +----------------+
                  1 row in set (0.00 sec)
                  Ist aber logisch oder?

                  Kommentar


                  • #10
                    Danke für alles!
                    Es gibt also mehrere Möglichkeiten. Wer macht jetzt einen Benchmark? Niemand? OK!

                    Kommentar

                    Lädt...
                    X