Zitat von marie123
Beitrag anzeigen
Ankündigung
Einklappen
Keine Ankündigung bisher.
MAX() in einer foreach Schleife
Einklappen
Neue Werbung 2019
Einklappen
Dieses Thema ist geschlossen.
X
X
-
-
Zitat von marie123 Beitrag anzeigenEs ist ja nicht so, als wenn ich nicht selbst schon nach Möglichkeiten gesucht hätte, das GROUP BY komplett zu umgehen.
Die Ausschließliche Nutzung von Aggregatfunktionen für jede Ausgabespalte.
Diese Frage kann eigentlich nur aufkommen, wenn man fehlerhaft konfiguriertes mysql einsetzt, folglich manchmal Glück hat bzw. nicht sieht, wann das Kleingedruckte zutrifft und wann nicht, also "zufällig" ein richtiges Ergebnis erhält und (deshalb vielleicht) die Problematik noch nicht verstanden hat.
Aggregat Funktionen können nur sinnvolle Ausgaben produzieren, wenn weitere, vorhandene Ausgabespalten gruppiert werden.
Einen Kommentar schreiben:
-
Zitat von erc Beitrag anzeigen
Ich mach sowas meistens im Kopf. Da gibts aber manchmal auch "Ausführungsfehler". ...
Und diese Tuppel werden gefiltert "erstes Element" > "zweites Element" (ON Klausel g.preiseingabe>t.preiseingabe). Hier hatte ich grade die Annhame, dass da genau ein Tuppel überig bleibt (3€, 3€). Was natürlich absoluter quatsch ist! Da kommt natürlich (2€, 1€), (3€, 1€), (3€, 2€) raus und der Query kann so nicht funktionieren... (Wäre die Annahme korrekt würde der Query wunderbar funktionieren )
Einen Kommentar schreiben:
-
Zitat von marie123 Beitrag anzeigenIch verstehe nur noch Bahnhof. Sei mir nicht böse, aber warum postest du nicht einfach die fertige Abfrage, dann kann man die testen und alles ist klar.
{
(1€, 1€)
(1€, 2€)
(1€, 3€)
(2€, 1€)
(2€, 2€)
(2€, 3€)
(3€, 1€)
(3€, 2€)
(3€, 3€)
}
Und diese Tuppel werden gefiltert "erstes Element" > "zweites Element" (ON Klausel g.preiseingabe>t.preiseingabe). Hier hatte ich grade die Annhame, dass da genau ein Tuppel überig bleibt (3€, 3€). Was natürlich absoluter quatsch ist! Da kommt (2€, 1€), (3€, 1€), (3€, 2€) raus und der Query kann so nicht funktionieren... (Wäre die Annahme korrekt würde der Query wunderbar funktionieren )
Einen Kommentar schreiben:
-
Zitat von erc Beitrag anzeigen
Sry, ich hab eine andere Anfrage vor Augen gehabt. Dieser self JOIN auf die Angebote um das maximal Gebot zu filtern hat es mir angetan. Der liefert das gewüschnte Ergebnis. Das GROUP BY und die Aggregat-Funktion sind in der Abfrage komplett überflüssig. Deswegen hab ich die gar nicht wahrgenommen und deswegen liefert der Query trotzdem auch das richtige Ergebnis.
(Der Vergleich muss mit >= gemacht werden, ansonsten funktioniert der Query nicht wenn nur ein Gebot geacht wurde).
*edit* obwohl das OR zerhauts u.U...
Einen Kommentar schreiben:
-
Zitat von marie123 Beitrag anzeigenNur daß es eben nicht funktioniert - in diesem Falle, weil es gegen die ONLY_FULL_GROUP_BY-Beschränkung verstößt und in diesem Falle die Beschränkung auch völlig zu Recht zu beachten wäre.
(Der Vergleich muss mit >= gemacht werden, ansonsten funktioniert der Query nicht wenn nur ein Gebot geacht wurde).
*edit* obwohl das OR zerhauts u.U...
*edit2* ok, kann so doch nicht funktionieren... g.preiseingabe>t.preiseingabe ist mehrfach wahr pro Auktion, aber auch nie füs höchste Gebot.
Einen Kommentar schreiben:
-
Zitat von erc Beitrag anzeigen
Nicht bettel! Eigeninitiative... es gibt heute soviele Möglichkeiten sich in dem Bereich weiterzubilden. Und insbesondere lernst du in der Branche nie aus.
Das ist die Kehrseite der Medaille. Wenn ich mir hier so manches Thread anschaue frag ich mich auch.
Der Query ist unlogisch aufgebaut. Wenn ich für alle beendeten Angebote das maximal Gebot haben will, sollte die Anfrage doch schonmal mit der Tabelle angebote los gehen und nicht als LEFT JOIN am Ende sitzen. Gibt es Gebote für nicht existente Angebote?!
Angebote also hochzeihen und dann mit INNER JOIN (nur Angebote mit Geboten) bzw. LEFT JOIN (auch Angebote auf die nicht geboten wurde) weiter machen.
Ansonsten passt das von der Logik. Auf den Ansatz wäre ich nicht gekommen.
Statt von "Hochziehen" und INNER oder LEFT JOIN zu reden, schreib die Abfrage auf und probier sie aus. Du wirst sehen, ohne sub-select geht es nicht. Begründet habe ich das nun wirklich schon zu genüge.
Einen Kommentar schreiben:
-
Zitat von king-ich Beitrag anzeigenDas Lustige, (oder vielmehr Traurige): Seit über 10 Jahren bettel ich nach einem Bildungsgutschein für den Bereich Webentwicklung, ohne Erfolg.
Zitat von hausl Beitrag anzeigenLeider ja, Stackoverflow-Prinzip. Egal wie scheisse dein Code ist und wie viele Fehler und Lücken du darin hast.. wenn du keine "Antwort auf die Frage" gibst wirst du gerügt. Ist mir selbst schon passiert, dann habe ich es dort gelassen. So viel zu deren Eingangs-Slogan "... for developers to learn". Na eh bei gnadenlosen Q&A lernt man sicher viel.. /Irnoie-Off .
Zitat von protestix Beitrag anzeigen
Gerne
PHP-Code:SELECT g.id, g.angebot_id, MAX(g.preiseingabe) AS Höchstgebot, g.kunde AS `abgegeben von`, FROM_UNIXTIME(min(g.`timestamp`)) AS `Datum Uhrzeit`, a.titel AS `Artikel`
FROM gebote g
INNER JOIN gebote t ON (g.angebot_id=t.angebot_id AND g.preiseingabe>t.preiseingabe) OR
(g.preiseingabe=t.preiseingabe AND g.timestamp<t.timestamp)
LEFT JOIN angebote a ON g.angebot_id = a.Auktionsnummer
GROUP BY g.angebot_id, a.titel
Angebote also hochzeihen und dann mit INNER JOIN (nur Angebote mit Geboten) bzw. LEFT JOIN (auch Angebote auf die nicht geboten wurde) weiter machen.
Ansonsten passt das von der Logik. Auf den Ansatz wäre ich nicht gekommen.
Einen Kommentar schreiben:
-
Zitat von protestix Beitrag anzeigen
Gerne
PHP-Code:SELECT g.id, g.angebot_id, MAX(g.preiseingabe) AS Höchstgebot, g.kunde AS `abgegeben von`, FROM_UNIXTIME(min(g.`timestamp`)) AS `Datum Uhrzeit`, a.titel AS `Artikel`
FROM gebote g
INNER JOIN gebote t ON (g.angebot_id=t.angebot_id AND g.preiseingabe>t.preiseingabe) OR
(g.preiseingabe=t.preiseingabe AND g.timestamp<t.timestamp)
LEFT JOIN angebote a ON g.angebot_id = a.Auktionsnummer
GROUP BY g.angebot_id, a.titel
Code:SELECT @@session.sql_mode;
Ergänzg.: Hat sich inzwischen bestätigt. Fügt man die nach (lt. protestix ) "Standard" bzw. eingeschaltetem ONLY_FULL_GROUP_BY (was ja dann dem "Standard" entspräche) erforderlichen Spalten im GROUP BY hinzu und fügt man weitere Gebote in die betr. Tabelle ein, wird die Gruppierung unter Einschluß von 'kunde' durchgeführt. Man sieht am Ergebnis der Abfrage dann sehr deutlich, daß "King Ich" im Abfrageergebnis zufällig über dem Eintrag zu "Maxi" steht. Deshalb nimmt das SQL "in seiner Not" (weil es ja nicht alle Bieter in ein einziges Feld quetschen kann) diesen.
Übrigens: Netter Versuch, protestix !
Einen Kommentar schreiben:
-
Zitat von Meister1900 Beitrag anzeigenIch lasse mir aber gerne anhand des Dumps in #15 zeigen, wie man das ohne Sub-Select lösen kann.
PHP-Code:SELECT g.id, g.angebot_id, MAX(g.preiseingabe) AS Höchstgebot, g.kunde AS `abgegeben von`, FROM_UNIXTIME(min(g.`timestamp`)) AS `Datum Uhrzeit`, a.titel AS `Artikel`
FROM gebote g
INNER JOIN gebote t ON (g.angebot_id=t.angebot_id AND g.preiseingabe>t.preiseingabe) OR
(g.preiseingabe=t.preiseingabe AND g.timestamp<t.timestamp)
LEFT JOIN angebote a ON g.angebot_id = a.Auktionsnummer
GROUP BY g.angebot_id, a.titel
Einen Kommentar schreiben:
-
Zitat von Meister1900 Beitrag anzeigenSorry, für Off-Topic, ...
Wenn mir jemand wie "Marie" einen seitenweisen Roman auf Deutsch schreibt, ...
Einen Kommentar schreiben:
-
Zitat von hausl Beitrag anzeigen
Leider ja, Stackoverflow-Prinzip. Egal wie scheisse dein Code ist und wie viele Fehler und Lücken du darin hast.. wenn du keine "Antwort auf die Frage" gibst wirst du gerügt. Ist mir selbst schon passiert, dann habe ich es dort gelassen. So viel zu deren Eingangs-Slogan "... for developers to learn". Na eh bei gnadenlosen Q&A lernt man sicher viel.. /Irnoie-Off .
Ist dann genau das Thema hier oben, welchen Anspruch hat ein Forum / eine Community. Und hier ist es eigentlich schon so, dass Lernen vor "Hauptsache es läuft" steht, daher wirkt es oft auch "Oberlehrerhaft". Ist halt einfach oft auch nötig. Und hängt natürlich auch vom Fragesteller, dessen Interessen und Motiv ab, keine Frage. Manche finden es geil dieses und jenes jetzt zu kennen oder zu benennen können (= gelernt zu haben), andere ist es sch.. egal, solange der Kot(sic!) läuft.
Die Aufgabe war ja auch erstmal nicht einfach, denn es ging um eine zwar bekannte, aber deswegen nicht einfachere Problematik im Zusammenhang mit dem GROUP BY-Clause: Inhaltlich besprochen wurde die Thematik in einem anderen Thread, weil sie von einem anderen User dort hineingetragen wurde.- Um nicht alles wiederholen zu müssen, bitte ich Interessierte zunächst mal nochmal einen Blick auf die Beiträge #32 und #34 zu werfen. Problem ist:
Der TE möchte Maximalwerte und benutzt dazu korrekterweise die seit langem existierende Aggregation mit dem GROUP BY-Clause und Aggregationsfunktion, hier max(). Nun kann ihm die Aggregation aber zunächst mal nur das Höchstgebot zum jeweiligen Angebot = Ware liefern, nicht aber den Bieter, der dieses Gebot abgegeben hat. Diesen Bieter in der gleichen Abfrage auch zu ermitteln und damit Datensätze nach dem Schema "Angebot - Höchstgebot zu diesem Angebot - Name des Bieters" zu erzeugen, war also die Aufgabe. - Ob MySQL oder ein anderes DBMS diese Aufgabe - oberflächlich betrachtet - nun löst oder nicht, dabei eine Fehlermeldung ausgibt oder nicht: Die Aufgabenstellung ist, wie in #34 begründet, ohne einen Sub-Select nicht lösbar. Bezieht man dies nochmal ausdrücklich auf die Konstruktion GROUP BY + Aggregatfunktion, muß man es noch schärfer formulieren: sie ist prinzipiell nicht lösbar. Warum? Dazu zitiere ich mich erstmal selbst mit dem Punkt 3. aus #34:Läßt man 'kunde' nur beim GROUP BY weg, funktioniert die Abfrage zwar in MySQL (und das ist auch richtig so! Es ist an uns als Entwickler, zu erkennen, ob die Nutzung dieser Möglichkeit Sinn macht), ist aber einfach unsinnig, weil von den bis zu 3 verschiedenen Bietern ja nur einer genannt werden kann.
a. Nicht-Nennung der Spalte 'kunde' in beiden Listen:Code:SELECT MAX(preiseingabe) AS max, angebote.Auktionsnummer, angebote.titel FROM gebote LEFT JOIN angebote ON gebote.angebot_id = angebote.Auktionsnummer GROUP BY angebote.Auktionsnummer, angebote.titel
b. Nennung von 'kunde' in beiden Listen:Code:SELECT gebote.kunde, MAX(preiseingabe) AS max, angebote.Auktionsnummer, angebote.titel FROM gebote LEFT JOIN angebote ON gebote.angebot_id = angebote.Auktionsnummer GROUP BY kunde, angebote.Auktionsnummer, angebote.titel
Warum ist aber nun die oben aus #34 zitierte Lösung keine wirkliche Lösung?
Auch hierzu zunächst mal der SQL-Code:Code:SELECT gebote.kunde, MAX(preiseingabe) AS max, angebote.Auktionsnummer, angebote.titel FROM gebote LEFT JOIN angebote ON gebote.angebot_id = angebote.Auktionsnummer GROUP BY angebote.Auktionsnummer, angebote.titel
o aggregiert werden oder
o von der "führenden" Spalte der Gruppe, hier angebote.Auktionsnummer funktional abhängig sein,
weil sonst in der Spalte 'kunde', die nicht aggregiert wird, mehrere Werte auftauchen müssten. Dies ist aber nicht möglich, also zeigt SQL einen zufälligen Wert an, hier "Maxi", obwohl "King Ich" die Auktion gewonnen hat. - Ob nun ein DBMS den SQL-Standard "verletzt"* oder nicht (Es gibt mind. ein DBMS, nämlich MySQL, das den obigen Code ausführt, ohne einen Fehler zu erzeugen, wenn man dort die Einstellung ONLY_FULL_GROUP_BY deaktiviert.), Tatsache ist: Diese Abfrage ist unsinnig und kann nur ein zufälliges, i.d.R. falsches Ergebnis erbringen.
- Letzteres ist der Grund, warum der Sub-Select unausweichlich ist.
- 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.
- Nochmal zugespitzt: Es handelt sich hier nicht um einen "Fehler", sondern um einen zusätzlichen "Service".
- Alles, was man dazu noch wissen sollte, findet sich hier: https://dev.mysql.com/doc/refman/5.7...-handling.html
____________________________________________
* ob es wirklich der Fall ist, daß dies eine Verletzung ist, wissen wir nicht, weil diese Behauptung bisher hier nie belegt wurde
Einen Kommentar schreiben:
- Um nicht alles wiederholen zu müssen, bitte ich Interessierte zunächst mal nochmal einen Blick auf die Beiträge #32 und #34 zu werfen. Problem ist:
-
Sorry, für Off-Topic, aber ich werde bei StackOverflow zu 99% immer fündig, egal was für ein Problem. Die Herausforderung ist nur, das Problem möglichst gut auf englisch formulieren zu können und die vermeintliche Lösung auf das eigene Problem adaptieren zu können.
Und ich persönlich lerne am Besten, in dem ich Code oder Lösungen von anderen sehe und versuche diese zu verstehen und indem ich in die offziellen Dokus / Manuals schaue. Letzteres wird m.E. viel zu wenig gemacht von den Fragestellern hier im Forum.
Wenn mir jemand wie "Marie" einen seitenweisen Roman auf Deutsch schreibt, der dann auch noch in elenden Diskussionen ausartet, wo man hinterher als Anfänger gar nicht mehr weiss, wo man dran ist, weiß ich nicht, ob das hilfreich ist.
Erst Recht in einer Welt, wo alle nur noch im Stress sind, "so schnell wie möglich" eine Lösung finden zu "müssen" oder bei denen, wo die Welt nur noch aus 280 Zeichen besteht und Youtube-Videos spätestens nach 2 Minuten weggeklickt werden, weil die persönliche Aufmerksamkeitsspanne unter der eines Goldfisches liegt.
- 2 Likes
Einen Kommentar schreiben:
-
Zitat von marie123 Beitrag anzeigen"Die Hauptsache ist nicht, daß dein Script jetzt läuft, sondern daß bzw. was du daraus gelernt hast:"
...
Aber ehrlich: Ist das hier nicht fast immer so?
Ist dann genau das Thema hier oben, welchen Anspruch hat ein Forum / eine Community. Und hier ist es eigentlich schon so, dass Lernen vor "Hauptsache es läuft" steht, daher wirkt es oft auch "Oberlehrerhaft". Ist halt einfach oft auch nötig. Und hängt natürlich auch vom Fragesteller, dessen Interessen und Motiv ab, keine Frage. Manche finden es geil dieses und jenes jetzt zu kennen oder zu benennen können (= gelernt zu haben), andere ist es sch.. egal, solange der Kot(sic!) läuft.
- 1 Likes
Einen Kommentar schreiben:
-
Zitat von Perry Staltic Beitrag anzeigenIch meinte, dass er nicht wirklich etwas gelernt hat.
Aber ehrlich: Ist das hier nicht fast immer so? Ich kann's auch nicht ganz nachvollziehen, aber irgendwie meinen die Leute, durch 25mal abgucken könne man was lernen.
Einen Kommentar schreiben:
Einen Kommentar schreiben: