Ankündigung

Einklappen
Keine Ankündigung bisher.

MAX() in einer foreach Schleife

Einklappen

Neue Werbung 2019

Einklappen
Dieses Thema ist geschlossen.
X
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • king-ich
    hat ein Thema erstellt MAX() in einer foreach Schleife.

    MAX() in einer foreach Schleife

    Hallo.
    Ich hab nach langer Zeit mal wieder eine Frage, mit der Bitte mir zu helfen..:

    Folgender Code soll mir in einer foreach Schleife Alle beendeten Auktionen mit dem jeweiligem Höchstgebot anzeigen.

    Ich hab den Code gefühlt 10000 mal umgeschrieben, mich mit google gestritten, und komme allein nicht weiter..
    Code:
    $sql = "SELECT gebote.kunde, MAX(preiseingabe) AS max, angebote.Auktionsnummer, angebote.titel
    FROM gebote LEFT JOIN angebote ON gebote.angebot_id = angebote.Auktionsnummer
    WHERE timediff(now(), angebote.dauer) > 0 AND angebote.user = '{$user}'";
    Ein Ergebnis war, dass Alle Gebote angezeigt wurden, ein anderes, dass ein einzelner Kunde (scheinbar willkürlich) mit dem höhsten Gebot in der Datenbank angezeigt wurde.

    Ich brauche Hilfe.

  • Arne Drews
    antwortet
    Öhm... Wie war die Frage nochmal? Ach ja... ist ja bereits seit #35 gelöst für den TE...

    [MOD: geschlossen]

    Einen Kommentar schreiben:


  • marie123
    antwortet
    Zitat von Perry Staltic Beitrag anzeigen

    Nein! Ich weiß nicht, wie man so borniert sein kann, falsche Ergebnisse zu ignorieren ...
    Sei doch bitte so freundlich und höflich, richtig zu lesen und auch zu verstehen. In welchem Teil/Satz meiner Ausführungen ignoriere ich falsche Ergebnisse?

    Einen Kommentar schreiben:


  • akretschmer
    antwortet
    Boah, Du hast so Recht! Ich hab es einfach in den Skat gedrückt

    Einen Kommentar schreiben:


  • Perry Staltic
    antwortet
    Zitat von akretschmer Beitrag anzeigen
    einfach ignorieren, würde ich vorschlagen.
    Nein! Ich weiß nicht, wie man so borniert sein kann, falsche Ergebnisse zu ignorieren und mit irgendwelchen menschlichen Case ..When .. Kascaden zu übertünchen. Wie man on top die Sinnhaftigkeit des extra von den Entwicklern ergänzten Reparaturschalters in Abrede stellen kann und auch noch versucht zu vermitteln, dass es gerade für Anfänger eine prima Sache ist, mit dieser Scheiße zu lernen.

    Wo ist der Benefit, was ist das Lernplus an diesem System? Bitte aufführen, was es gerade für Anfänger so lernenswert und vorteilhaft macht!
    Ich werde mich jeder einzelnen Antwort und jedem genannten Feature widmen!

    Einen Kommentar schreiben:


  • akretschmer
    antwortet
    Um mal etwas FÜR MySQL zu sagen (oh Gott, die Hölle friert ein...): es kann offenbar "loose index scan" oder auch als "skip index scan" bekannte Dinge, die PG (derzeit) nicht kann - zumindest nicht direkt. Siehe https://wiki.postgresql.org/wiki/Loose_indexscan . Das ist cool. Richtig cool! Ich hab grad ein Ticket, wo es um sowas geht... der Workaround funktioniert, und ein Patch (für 13?) ist in Sicht, ... stay tuned for more!

    Einen Kommentar schreiben:


  • akretschmer
    antwortet
    protestix einfach ignorieren, würde ich vorschlagen. Ich bin eh raus: tl;dr. Diese Diskussion ist schlicht flüssiger als Wasser. Also überflüssig.

    Einen Kommentar schreiben:


  • protestix
    antwortet
    marie123 oder wie auch immer...
    Unglaublich wie viel Energie du in ein Problem investierst, das für die Meisten gar nicht existiert.
    Dass du zudem Muttersprachlern die Fähigkeit absprichst Formulierungen richtig zu verwenden setz, meiner Meinung nach, dem Ganzen die Krone auf und zeigt wie lächerlich du dich machst.

    Einen Kommentar schreiben:


  • marie123
    antwortet
    Zitat von Meister1900 Beitrag anzeigen

    Die MySQL Entwickler begründen das unter https://dev.mysql.com/doc/refman/5.7...-handling.html so:
    1. Zunächst muß man mal konstatieren, daß das eine ungeschickte Formulierung ist, korrekt hätte es besser heißen sollen "...all values in each nonaggregated column not named in the GROUP BY are the same within each group." Gut, so gut kann ich jetzt auch kein Englisch, daß ich beurteilen kann, ob dies von muttersprachlichen Englischsprechenden nicht ohnehin so verstanden werden würde.
    2. So oder so - die Aussage beschreibt zunächst einmal nur das, was den Unterschied macht und ist demnach (scheinbar) trivial: Sind nämlich die Werte derjenigen Spalte in der SELECT-Liste, die weder aggregiert wird noch im Group by steht, für eine einzelne Gruppe unterschiedlich, würde dies im Falle der Deaktivierung von ONLY_FULL_GROUP_BY und Beibehaltung der Gruppe (also ohne die "fragliche" Spalte) zu einer Mehrdeutigkeit der Auswahl für diese zusätzliche Spalte und damit zu einem zufälligen Ergebnis führen. Im Falle der Aufnahme der Spalte in die GROUP BY-Liste resultiert demgegenüber eine "Verfeinerung" der Gruppierung (im Sinne von einer größeren Anzahl von Gruppen mit weniger Mitgliedern), die auch nicht hilfreich ist.
    3. Nun folgt natürlich zwingend die absolut logische schlußfolgernde Frage: Wenn das ONLY_FULL_GROUP_BY nicht hilfreich ist, wann kann es denn dann überhaupt hilfreich sein, ist es damit nicht doch überflüssig?
    4. Um dies zu überprüfen, müssen wir uns die Doku nochmal genauer anschauen und dabei (leider für die, die dies nicht gerne tun ... ) ein wenig Lesearbeit investieren, hier erstmal der Link: https://dev.mysql.com/doc/refman/5.7...-handling.html
      Dort wird ausführlich dargelegt, was MySQL mit Abfragen macht, die diese Problematik aufweisen, Stichwörter sind "funktionale Abhängigkeit" und "Eindeutigkeit". Und es wird deutlich: "Eigentlich" müssten doch alle Fälle, in denen die vorgenannte Konstellation so gegeben ist, daß eine Aufnahme der fraglichen Spalte in die SELECT-Liste unschädlich ist, erfaßt werden, da doch - wie dort ausgeführt - MySQL über die Befähigung zur Detektion solcher Fälle besitzt. Oder?
      Tatsächlich beinhaltet das, was dort angeführt wird auch die Kehrseite als komplett logische Schlußfolgerung: Wenn MySQL "solche Fälle" entdecken kann und dann eine Diskrepanz zwischen SELECT- und GROUP BY-Liste auch bei aktiviertem ONLY_FULL_GROUP_BY geduldet wird, dann steht und fällt diese Option damit, daß dies "Befähigung" lückenlos funktioniert. Tatsächlich funktioniert sie nicht lückenlos, und deshalb ist die Deaktivierung von ONLY_FULL_GROUP_BY auch sinnvoll.
    5. Und hier liegt dann auch die wirkliche Bedeutung des von Dir zitierten Satzes, die in 5 scheinbar harmlosen Wörtchen versteckt ist: " ... due to some property of the data ...". Was sollen das denn eigentlich für "gewisse Eigenschaften der Daten" sein, wo noch nicht einmal die Detektion funktionaler Abhängigkeiten und entsprechende "Tolerierung" (von "überschüssigen" SELECT-Spalten) hilft? Antwort ist: Das ist die falsche Frage, es ist nämlich nicht der Punkt, daß MySQL richtig arbeitet, wenn es die Abhängigkeit entdeckt, sondern: ob es die Abhängigkeit entdeckt. Wie unter 4. bereits geschrieben: Das ist nicht immer der Fall.
    Es folgen nun ein paar Abfragen, die zeigen, daß die Detektion nicht immer funktioniert und daß für solche Abfragen die Deaktivierung von ONLY_FULL_GROUP_BY sinnvoll und hilfreich ist:

    TEST-DATENBANK
    Folgende Test-DB muß verwendet werden:
    Code:
    -- phpMyAdmin SQL Dump
    -- version 4.8.5
    -- https://www.phpmyadmin.net/
    --
    -- Host: 127.0.0.1
    -- Erstellungszeit: 17. Nov 2019 um 18:20
    -- Server-Version: 10.1.38-MariaDB
    -- PHP-Version: 7.3.2
    
    SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
    SET AUTOCOMMIT = 0;
    START TRANSACTION;
    SET time_zone = "+00:00";
    
    
    /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
    /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
    /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
    /*!40101 SET NAMES utf8mb4 */;
    
    --
    -- Datenbank: `groupby_ex`
    --
    
    -- --------------------------------------------------------
    
    --
    -- Tabellenstruktur für Tabelle `tbl_abteilung`
    --
    
    CREATE TABLE `tbl_abteilung` (
      `AbteilungID` int(11) NOT NULL,
      `FilialeID_FK` int(11) NOT NULL,
      `AbteilungBez` text NOT NULL,
      `AbteilungLeiterMbID` int(11) NOT NULL
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    
    --
    -- Daten für Tabelle `tbl_abteilung`
    --
    
    INSERT INTO `tbl_abteilung` (`AbteilungID`, `FilialeID_FK`, `AbteilungBez`, `AbteilungLeiterMbID`) VALUES
    (1, 1, 'VerwaltungHH', 3),
    (2, 1, 'ProduktionHH', 9),
    (3, 1, 'VertriebHH', 5),
    (4, 1, 'ZentraleDV_HH', 6),
    (5, 2, 'VerwaltungM', 4),
    (6, 2, 'ProduktionM', 10),
    (7, 2, 'VertriebM', 7),
    (8, 2, 'ZentraleDV_M', 8);
    
    -- --------------------------------------------------------
    
    --
    -- Tabellenstruktur für Tabelle `tbl_filiale`
    --
    
    CREATE TABLE `tbl_filiale` (
      `FilialeID` int(11) NOT NULL,
      `FilialeBez` text NOT NULL,
      `FilialLeiterMbID_FK` int(11) NOT NULL
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    
    --
    -- Daten für Tabelle `tbl_filiale`
    --
    
    INSERT INTO `tbl_filiale` (`FilialeID`, `FilialeBez`, `FilialLeiterMbID_FK`) VALUES
    (1, 'Hamburg', 1),
    (2, 'München', 2);
    
    -- --------------------------------------------------------
    
    --
    -- Tabellenstruktur für Tabelle `tbl_mitarbeiter`
    --
    
    CREATE TABLE `tbl_mitarbeiter` (
      `MitarbeiterID` int(11) NOT NULL,
      `Nachname` text NOT NULL,
      `PersonalNr` text NOT NULL,
      `AbteilungID_FK` int(11) NOT NULL,
      `Gehalt` decimal(10,0) NOT NULL
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    
    --
    -- Daten für Tabelle `tbl_mitarbeiter`
    --
    
    INSERT INTO `tbl_mitarbeiter` (`MitarbeiterID`, `Nachname`, `PersonalNr`, `AbteilungID_FK`, `Gehalt`) VALUES
    (1, 'Meyer', '01V0001', 1, '5000'),
    (2, 'Müller', '02P0002', 6, '5500'),
    (3, 'Schulz', '01V0003', 1, '4500'),
    (4, 'Müller', '02V0004', 5, '4500'),
    (5, 'Wagner', '01VT0005', 3, '4500'),
    (6, 'Weber', '01IT0006', 4, '4500'),
    (7, 'Schulz', '02VT0007', 7, '4500'),
    (8, 'Reinhard', '02IT0008', 8, '4500'),
    (9, 'Siebert', '01P0009', 2, '4500'),
    (10, 'Schrader', '02P0010', 6, '4500');
    
    --
    -- Indizes der exportierten Tabellen
    --
    
    --
    -- Indizes für die Tabelle `tbl_abteilung`
    --
    ALTER TABLE `tbl_abteilung`
      ADD PRIMARY KEY (`AbteilungID`);
    
    --
    -- Indizes für die Tabelle `tbl_filiale`
    --
    ALTER TABLE `tbl_filiale`
      ADD PRIMARY KEY (`FilialeID`);
    
    --
    -- Indizes für die Tabelle `tbl_mitarbeiter`
    --
    ALTER TABLE `tbl_mitarbeiter`
      ADD PRIMARY KEY (`MitarbeiterID`);
    
    --
    -- AUTO_INCREMENT für exportierte Tabellen
    --
    
    --
    -- AUTO_INCREMENT für Tabelle `tbl_abteilung`
    --
    ALTER TABLE `tbl_abteilung`
      MODIFY `AbteilungID` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=9;
    
    --
    -- AUTO_INCREMENT für Tabelle `tbl_filiale`
    --
    ALTER TABLE `tbl_filiale`
      MODIFY `FilialeID` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=3;
    
    --
    -- AUTO_INCREMENT für Tabelle `tbl_mitarbeiter`
    --
    ALTER TABLE `tbl_mitarbeiter`
      MODIFY `MitarbeiterID` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=11;
    COMMIT;
    
    /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
    /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
    /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
    ABFRAGEN
    Code:
    -- Funktioniert bei aktiviertem ONLY_FULL_GROUP_BY, hat aber auch keine "überschüssige" Spalten:
    SELECT tbl_filiale.FilialeBez, t_fl.Nachname AS Filialleiter, t_fl.PersonalNr AS FilLeiterPNr
    , tbl_abteilung.AbteilungBez, t_abt.Nachname AS AbtLeiter, t_abt.PersonalNr AS AbtLeiterPNr
    , Sum(t_mb.Gehalt) AS SummevonGehalt
    FROM (((tbl_filiale INNER JOIN tbl_abteilung ON tbl_filiale.FilialeID = tbl_abteilung.FilialeID_FK)
    INNER JOIN tbl_mitarbeiter AS t_fl ON tbl_filiale.FilialLeiterMbID_FK = t_fl.MitarbeiterID)
    INNER JOIN tbl_mitarbeiter AS t_abt ON tbl_abteilung.AbteilungLeiterMbID = t_abt.MitarbeiterID)
    INNER JOIN tbl_mitarbeiter AS t_mb ON tbl_abteilung.AbteilungID = t_mb.AbteilungID_FK
    GROUP BY tbl_filiale.FilialeBez, Filialleiter, FilLeiterPNr, tbl_abteilung.AbteilungBez
    , AbtLeiter, AbtLeiterPNr
    ORDER BY tbl_filiale.FilialeID, tbl_abteilung.AbteilungID;
    
    -- Funktioniert nur bei deaktiviertem ONLY_FULL_GROUP_BY:
    SELECT tbl_filiale.FilialeBez, tbl_filiale.FilialeID, t_fl.Nachname AS Filialleiter
    , t_fl.PersonalNr AS FilLeiterPNr, tbl_abteilung.AbteilungBez, tbl_abteilung.AbteilungID
    , t_abt.Nachname AS AbtLeiter, t_abt.PersonalNr AS AbtLeiterPNr, Sum(t_mb.Gehalt) AS SummevonGehalt
    FROM (((tbl_filiale INNER JOIN tbl_abteilung ON tbl_filiale.FilialeID = tbl_abteilung.FilialeID_FK)
    INNER JOIN tbl_mitarbeiter AS t_fl ON tbl_filiale.FilialLeiterMbID_FK = t_fl.MitarbeiterID)
    INNER JOIN tbl_mitarbeiter AS t_abt ON tbl_abteilung.AbteilungLeiterMbID = t_abt.MitarbeiterID)
    INNER JOIN tbl_mitarbeiter AS t_mb ON tbl_abteilung.AbteilungID = t_mb.AbteilungID_FK
    GROUP BY tbl_filiale.FilialeID, Filialleiter, FilLeiterPNr, tbl_abteilung.AbteilungID
    , AbtLeiter, AbtLeiterPNr
    ORDER BY tbl_filiale.FilialeID, tbl_abteilung.AbteilungID;
    
    -- Funktioniert ebenfalls nur bei deaktiviertem ONLY_FULL_GROUP_BY:
    SELECT tbl_filiale.FilialeBez, t_fl.Nachname AS Filialleiter, t_fl.PersonalNr AS FilLeiterPNr
    , tbl_abteilung.AbteilungBez, t_abt.Nachname AS AbtLeiter, t_abt.PersonalNr AS AbtLeiterPNr
    , Sum(t_mb.Gehalt) AS SummevonGehalt
    FROM (((tbl_filiale INNER JOIN tbl_abteilung ON tbl_filiale.FilialeID = tbl_abteilung.FilialeID_FK)
    INNER JOIN tbl_mitarbeiter AS t_fl ON tbl_filiale.FilialLeiterMbID_FK = t_fl.MitarbeiterID)
    INNER JOIN tbl_mitarbeiter AS t_abt ON tbl_abteilung.AbteilungLeiterMbID = t_abt.MitarbeiterID)
    INNER JOIN tbl_mitarbeiter AS t_mb ON tbl_abteilung.AbteilungID = t_mb.AbteilungID_FK
    GROUP BY tbl_filiale.FilialeBez, tbl_abteilung.AbteilungBez
    ORDER BY tbl_filiale.FilialeID, tbl_abteilung.AbteilungID;

    Einen Kommentar schreiben:


  • Meister1900
    antwortet
    Zitat von Arne Drews Beitrag anzeigen
    Die ( sinnvollen ) Beispiele hätte ich gern mal gesehen, hast Du Links für mich?
    Die MySQL Entwickler begründen das unter https://dev.mysql.com/doc/refman/5.7...-handling.html so:

    Disabling ONLY_FULL_GROUP_BY is useful primarily when you know that, due to some property of the data, all values in each nonaggregated column not named in the GROUP BY are the same for each group.

    Einen Kommentar schreiben:


  • marie123
    antwortet
    Zitat von Arne Drews Beitrag anzeigen
    Die (sinnvollen) Beispiele hätte ich gern mal gesehen, ...Jetzt, wo es gerade in Deine Argumentation passt, soll das wieder nur eine Option sein, ...macht es das noch lange nicht zu einer nützlichen Einstellung, sorry.
    Ließ dir bitte nochmal deinen Beitrag durch, langsam Wort für Wort. Und dann sag mir bitte, was dir auffällt. Insbesondere der 3. Satz, 1. Halbsatz.

    Einen Kommentar schreiben:


  • akretschmer
    antwortet
    distinct on() ist cool - und nicht im SQL-Standard, sondern PostgreSQL-spezifisch. Ist so auch dokumentiert.

    Einen Kommentar schreiben:


  • Arne Drews
    antwortet
    Denn ist ja doch noch etwas Licht am Ende des Tunnels für Postgres...

    Einen Kommentar schreiben:


  • akretschmer
    antwortet
    Arne Drews , Du wirst lachen, *etwas* geht das sogar im PostgreSQL:

    Code:
    test=*# create table demo(a int primary key, b int);
    CREATE TABLE
    test=*# select a, max(b) from demo;
    ERROR:  column "demo.a" must appear in the GROUP BY clause or be used in an aggregate function
    LINE 1: select a, max(b) from demo;
                   ^
    test=*# select distinct on (a) a, b from demo order by a, b desc;
     a | b
    ---+---
    (0 rows)
    Quasi eine Alternative für max(), ohne group by ...

    Einen Kommentar schreiben:


  • Arne Drews
    antwortet
    Zitat von marie123 Beitrag anzeigen
    MySQL bietet spätestens seit Versionen höher als 5.7.5 die Möglichkeit, die Einstellung ONLY_FULL_GROUP_BY zu deaktivieren, was die Ausführung fehlerhafter Abfrage wie die oben zuletzt wiedergegebene ermöglicht. Dies ist also kein "Fehler" und auch keine "Standard-Verletzung", sondern lediglich eine Wahlmöglichkeit, die im phpmyadmin vorgesehen ist und nicht etwa, wie Arne Drews im anderen Thread schreibt, darauf zurückzuführen, daß "ThirdParty-Tools diese [Einstellung] sinnfrei überschreiben". Diese Einstellung zu ändern, kann in anderen Konstellationen helfen, wofür es hier im Forum auch bereits Beispiele gab.
    Die ( sinnvollen ) Beispiele hätte ich gern mal gesehen, hast Du Links für mich?
    Ganz ehrlich, es wird immer bemängelt, dass MySQL genau dieses Verhalten aufzeigt, fehlerhaft gruppierte Queries mit Resultaten zu beliefern. Jetzt, wo es gerade in Deine Argumentation passt, soll das wieder nur eine Option sein, die sogar in einigen Fällen hilfreich sein soll? Dann schlage ich als nächstes akretschmer vor, dass er das mal als CustomerVoice für Postgres einwirft, der wird sich freuen...

    Und nur weil ThirdParty-Tools ( phpMyAdmin ist eins! ) die Möglichkeit bieten, es wieder zu deaktivieren, macht es das noch lange nicht zu einer nützlichen Einstellung, sorry.

    Einen Kommentar schreiben:

Lädt...
X