mysql, Query, Immer nur der letzte Eintrag – SELFHTML-Forum Forum als Ergänzung zum SELFHTML-Wiki und zur Dokumentation SELFHTML https://forum.selfhtml.org/self mysql, Query, Immer nur der letzte Eintrag Fri, 02 Apr 21 14:19:51 Z https://forum.selfhtml.org/self/2021/apr/02/mysql-query-immer-nur-der-letzte-eintrag/1786763#m1786763 https://forum.selfhtml.org/self/2021/apr/02/mysql-query-immer-nur-der-letzte-eintrag/1786763#m1786763 <p>Hallo,</p> <p>ich habe 2 Tabellen:</p> <pre><code class="block">1: ID1,Spalte1 2: ID2,ID1,Datum </code></pre> <p>Und meine Query ist:</p> <pre><code class="block">SELECT t1.ID11, t1.Spalte1, t2.ID2 FROM table1 t1 LEFT JOIN table2 t2 ON t1.ID1 = t2.ID1 </code></pre> <p>So erhalte ich alle Einträge aus table1 und zusätzlich auch die ID2, falls hierzu ein Eintrag in table2 vorhanden ist.</p> <p>Der kleine Sc hönheitsfehler ist, dass ich auch 5 Einträge aus table2 erhalte, falls 5 Einträge vorhanden sind. Mir würde aber der vom Datum her jeweils jüngste Eintrag aus table2 ausreichen.</p> <p>Wie mache ich das?</p> <p>Jörg</p> mysql, Query, Immer nur der letzte Eintrag Fri, 02 Apr 21 17:28:41 Z https://forum.selfhtml.org/self/2021/apr/02/mysql-query-immer-nur-der-letzte-eintrag/1786778#m1786778 https://forum.selfhtml.org/self/2021/apr/02/mysql-query-immer-nur-der-letzte-eintrag/1786778#m1786778 <p>Hallo Jörg,</p> <p>das ist mühsam und hässlich. Und ich nehme an, du möchtest auch eine Spalte2 aus table2 haben, sonst kannst Du auf den Join verzichten </p> <p>Du kannst mit einer Zusatzklausel den JOIN auf das jüngste Datum limitieren:</p> <pre><code class="block language-sql"><span class="token keyword">SELECT</span> t1<span class="token punctuation">.</span>ID1<span class="token punctuation">,</span> t1<span class="token punctuation">.</span>Spalte1<span class="token punctuation">,</span> t2<span class="token punctuation">.</span>ID2<span class="token punctuation">,</span> t2<span class="token punctuation">.</span>Spalte2 <span class="token keyword">FROM</span> table1 t1 <span class="token keyword">LEFT</span> <span class="token keyword">JOIN</span> table2 t2 <span class="token keyword">ON</span> t1<span class="token punctuation">.</span>ID1 <span class="token operator">=</span> t2<span class="token punctuation">.</span>ID1 <span class="token operator">AND</span> t2<span class="token punctuation">.</span>Datum <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">SELECT</span> <span class="token function">MAX</span><span class="token punctuation">(</span>Datum<span class="token punctuation">)</span> <span class="token keyword">FROM</span> table2 <span class="token keyword">WHERE</span> id <span class="token operator">=</span> t1<span class="token punctuation">.</span>ID1<span class="token punctuation">)</span> </code></pre> <p>Keine Ahnung wie gut der SQL Server das optimiert, das muss man messen. Ein Index, der ID2 und Datum enthält, ist vermutlich hilfreich.</p> <p>Eine weitere Alternative wäre, die Query zu teilen. Zuerst nur table1 lesen, dann table2, mit einem ORDER BY nach Datum absteigend, und einem Limit auf den ersten Treffer. Das sind dann zwei Queries an die DB - mit Hilfe einer Routine (Stored Procedure) könnte man ggf. erreichen, dass man nur einen Roundtrip zum DB Server braucht. Aber das lohnt vermutlich nur, wenn der auf einem separaten Computer läuft.</p> <p>Die Alternative ist Postprocessing des Query-Ergebnisses in der Programmiersprache. Wenn es in table2 viele Sätze zu einer ID gibt, ist die MAX-Query vermutlich besser. Das lässt sich nur in deiner konkreten Umgebung beobachten und messen.</p> <p><em>Rolf</em></p> <div class="signature">-- <br> sumpsi - posui - obstruxi </div> mysql, Query, Immer nur der letzte Eintrag Fri, 02 Apr 21 18:23:14 Z https://forum.selfhtml.org/self/2021/apr/02/mysql-query-immer-nur-der-letzte-eintrag/1786789#m1786789 https://forum.selfhtml.org/self/2021/apr/02/mysql-query-immer-nur-der-letzte-eintrag/1786789#m1786789 <p>Hallo Rolf,</p> <blockquote> <p>Du kannst mit einer Zusatzklausel den JOIN auf das jüngste Datum limitieren:</p> <pre><code class="block language-sql"><span class="token keyword">SELECT</span> t1<span class="token punctuation">.</span>ID1<span class="token punctuation">,</span> t1<span class="token punctuation">.</span>Spalte1<span class="token punctuation">,</span> t2<span class="token punctuation">.</span>ID2<span class="token punctuation">,</span> t2<span class="token punctuation">.</span>Spalte2 <span class="token keyword">FROM</span> table1 t1 <span class="token keyword">LEFT</span> <span class="token keyword">JOIN</span> table2 t2 <span class="token keyword">ON</span> t1<span class="token punctuation">.</span>ID1 <span class="token operator">=</span> t2<span class="token punctuation">.</span>ID1 <span class="token operator">AND</span> t2<span class="token punctuation">.</span>Datum <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">SELECT</span> <span class="token function">MAX</span><span class="token punctuation">(</span>Datum<span class="token punctuation">)</span> <span class="token keyword">FROM</span> table2 <span class="token keyword">WHERE</span> id <span class="token operator">=</span> t1<span class="token punctuation">.</span>ID1<span class="token punctuation">)</span> </code></pre> </blockquote> <p>Das habe ich versucht und es funktioniert, danke.</p> <p>Leider ergibt sich hieraus ein Problem, das ich nicht bedacht hatte:</p> <p>In table2 gibt es eine Flag-Spalte <code>XYZ(int 1)</code>. Und es sollen alle Einträge mit XYZ=0 angezeigt werden, während von denen mit XYZ=1 nur der jeweils älteste angezeigt werden soll. Sorry für die weitere Einschränkung, die ist mir selber erst gerade beim Testen aufgefallen.</p> <p>Jörg</p> mysql, Query, Immer nur der letzte Eintrag Fri, 02 Apr 21 20:27:36 Z https://forum.selfhtml.org/self/2021/apr/02/mysql-query-immer-nur-der-letzte-eintrag/1786794#m1786794 https://forum.selfhtml.org/self/2021/apr/02/mysql-query-immer-nur-der-letzte-eintrag/1786794#m1786794 <p>Hallo Jörg,</p> <p>naja, dann musst Du</p> <ul> <li>MIN(Datum) statt MAX(datum) verwenden, sonst kommt nicht der älteste</li> <li><strong>die MIN-Datum Bestimmung auf Sätze mit xyz=1 begrenzen</strong></li> <li>Alle sätze mit xyz=0 reinnehmen, unabhängig vom Datum.</li> </ul> <p>Das kriegst Du doch bestimmt hin. Gehört alles in das ON.</p> <p><code>ON (ids stimmen überein) AND ((Datum Stimmt) OR (xyz=0))</code></p> <p>Auf der linken Seite vom OR brauchst Du xyz=1 nicht abzufragen, das ist boolesche Optimierung. <code>(A AND B) OR (NOT A)</code> ist identisch zu <code>B OR (NOT A)</code>. Mach Dir eine Wahrheitstabelle wenn Du es nicht glaubst </p> <p><em>Rolf</em></p> <div class="signature">-- <br> sumpsi - posui - obstruxi </div> mysql, Query, Immer nur der letzte Eintrag Fri, 02 Apr 21 21:31:49 Z https://forum.selfhtml.org/self/2021/apr/02/mysql-query-immer-nur-der-letzte-eintrag/1786798#m1786798 https://forum.selfhtml.org/self/2021/apr/02/mysql-query-immer-nur-der-letzte-eintrag/1786798#m1786798 <p>Hallo Rolf,</p> <p>erstmal danke für die Hilfe und dann noch eine Korrektur, MAX() war schon korrekt, ich hatte vorhin fälschlich "älteste" geschrieben, gesucht wird aber nach wie vor der letzte, also jüngste Eintrag.</p> <blockquote> <p><code>ON (ids stimmen überein) AND ((Datum Stimmt) OR (xyz=0))</code></p> <p>Auf der linken Seite vom OR brauchst Du xyz=1 nicht abzufragen, das ist boolesche Optimierung. <code>(A AND B) OR (NOT A)</code> ist identisch zu <code>B OR (NOT A)</code>. Mach Dir eine Wahrheitstabelle wenn Du es nicht glaubst </p> </blockquote> <p>Da ich reiner Autodidakt bin und somit nicht per Studium verpflichtet war, habe ich noch nie eine Wahrheitstabelle angefertigt. Wenn ich nicht zufällig ein paar Informatikstudenten kennen würde, würde ich den Begriff gar nicht kennen. </p> <p>Ich kann mir aber vorstellen, was Du meinst und glaube es Dir, trotzdem habe ich es jetzt mal zum besseren verständnis (für mich) ohne bolsche Optimierung in die Query aufgenommen, nur kommt als Ergebnis imm,er noch nicht genau das heraus, was ich suche.</p> <p>Bei folgenden Daten der table2 z.b.</p> <pre><code class="block">ID XYZ Date 51 0 2021-04-01 60 0 2021-04-01 62 1 2021-04-01 63 1 2021-04-01 63 0 2021-04-02 </code></pre> <p>verliere ich mit folgender Query</p> <pre><code class="block">... AND (((t2.Datum = (SELECT MAX(Datum) FROM table2 t2 WHERE t2.ID = t1.ID) AND XYZ = 1) OR (XYZ = 0)) AND t2.del = 0) </code></pre> <p>den an 4.Stelle liegenden Datensatz aus der Ergebnismenge.</p> <p>Der soll zwar auch herausfallen, aber erst dann, wenn der an 5.Stelle liegende Datensatz mit derselben ID den XYZ-Flag 1 erhält.</p> <p>Vorher würde ich gerne beide in der Ergebnismenge haben.</p> <p>Danke für Deine Mühe + Hilfe und einen vorosterlichen Gruß,</p> <p>Jörg</p> mysql, Query, Immer nur der letzte Eintrag Fri, 02 Apr 21 22:19:17 Z https://forum.selfhtml.org/self/2021/apr/02/mysql-query-immer-nur-der-letzte-eintrag/1786799#m1786799 https://forum.selfhtml.org/self/2021/apr/02/mysql-query-immer-nur-der-letzte-eintrag/1786799#m1786799 <p>Hallo Jörg,</p> <p>tjaaa. Ich habe in meinem vorigen Posting ganz bewusst was fett gemacht. Und das hast Du nicht umgesetzt.</p> <p>Von wo bis wo geht der Subselect, der das Max-Datum bestimmt? Und was wird in dem Subselect nicht abgefragt? Eben </p> <p>Kannst Du übrigens sicherstellen, dass es zu einer ID und einem Datum immer nur einen Satz gibt? Denn andernfalls ist der "jüngste" nicht klar definiert und Du kriegst ggf. mehr als einen mit xyz=1.</p> <p>Wahrheitstabellen sind aber was ganz simples. Wenn man prüfen will, ob man einen logischen Ausdruck korrekt optimiert hat, sind sie unverzichtbar. Damit solltest Du Dich befassen.</p> <p><em>Rolf</em></p> <div class="signature">-- <br> sumpsi - posui - obstruxi </div> mysql, Query, Immer nur der letzte Eintrag Sat, 03 Apr 21 08:00:31 Z https://forum.selfhtml.org/self/2021/apr/02/mysql-query-immer-nur-der-letzte-eintrag/1786808#m1786808 https://forum.selfhtml.org/self/2021/apr/02/mysql-query-immer-nur-der-letzte-eintrag/1786808#m1786808 <p>Hallo Rolf,</p> <blockquote> <p>tjaaa. Ich habe in meinem vorigen Posting ganz bewusst was fett gemacht. Und das hast Du nicht umgesetzt.</p> </blockquote> <p>Ich hatte mich schon gefragt, warum das fett ist. </p> <blockquote> <p>Von wo bis wo geht der Subselect, der das Max-Datum bestimmt? Und was wird in dem Subselect nicht abgefragt? Eben </p> </blockquote> <p>Ich weiß wirklich nicht, wo ichs hinpacken soll :-( Ist irgendwie, wie beim Ostereier suchen. Da war ich auch nie sonderlich gut drin </p> <blockquote> <p>Kannst Du übrigens sicherstellen, dass es zu einer ID und einem Datum immer nur einen Satz gibt? Denn andernfalls ist der "jüngste" nicht klar definiert und Du kriegst ggf. mehr als einen mit xyz=1.</p> </blockquote> <p>Ja, das kann ich. Ich habe nämlich nur aufgrund geringerer Schreibarbeit hier eine Date-Spalte aufgeführt. In Wirklichkeit ist es eine Datetimespalte.</p> <blockquote> <p>Wahrheitstabellen sind aber was ganz simples. Wenn man prüfen will, ob man einen logischen Ausdruck korrekt optimiert hat, sind sie unverzichtbar. Damit solltest Du Dich befassen.</p> </blockquote> <p>Werde ich mir anschauen.</p> <p>Jörg</p> mysql, Query, Immer nur der letzte Eintrag Sat, 03 Apr 21 09:14:43 Z https://forum.selfhtml.org/self/2021/apr/02/mysql-query-immer-nur-der-letzte-eintrag/1786822#m1786822 https://forum.selfhtml.org/self/2021/apr/02/mysql-query-immer-nur-der-letzte-eintrag/1786822#m1786822 <p>Hallo Jörg,</p> <blockquote> <p>Ich weiß wirklich nicht, wo ichs hinpacken soll :-(</p> </blockquote> <p>SQL kann überraschend einfach sein, und auch überraschend komplex. Man muss komplexe Queries in ihre Teile gliedern.</p> <blockquote> <p>Ist irgendwie, wie beim Ostereier suchen. Da war ich auch nie sonderlich gut drin </p> </blockquote> <p>Wenn Du damit meinst, dass Du mit Geduld und strukturiertem Vorgehen ein Problem hast, dann ist deine Zukunft in der Computerwelt sehr steinig.</p> <pre><code class="block language-sql"><span class="token operator">AND</span> <span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">(</span>t2<span class="token punctuation">.</span>Datum <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">SELECT</span> <span class="token function">MAX</span><span class="token punctuation">(</span>Datum<span class="token punctuation">)</span> <span class="token keyword">FROM</span> table2 t2 <span class="token keyword">WHERE</span> t2<span class="token punctuation">.</span>ID <span class="token operator">=</span> t1<span class="token punctuation">.</span>ID<span class="token punctuation">)</span> <span class="token operator">AND</span> XYZ <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token operator">OR</span> <span class="token punctuation">(</span>XYZ <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">AND</span> t2<span class="token punctuation">.</span>del <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">)</span> </code></pre> <p>Der Subselect, der das Referenzdatum bestimmt, ist dieser:</p> <p><code>(SELECT MAX(Datum) FROM table2 t2 WHERE t2.ID = t1.ID)</code></p> <p>Dieser Subselect darf nur Sätze mit xyz=1 berücksichtigen.</p> <p>Und das tut man wie?</p> <p>Zugegeben, nachher sieht die Query merkwürdig aus, sie scheint dann zweimal nacheinander das gleiche abzufragen. Aber ich sagte ja eh schon, dass eine bestimmte Abfrage überflüssig sei </p> <p><em>Rolf</em></p> <div class="signature">-- <br> sumpsi - posui - obstruxi </div> mysql, Query, Immer nur der letzte Eintrag Sat, 03 Apr 21 09:36:34 Z https://forum.selfhtml.org/self/2021/apr/02/mysql-query-immer-nur-der-letzte-eintrag/1786828#m1786828 https://forum.selfhtml.org/self/2021/apr/02/mysql-query-immer-nur-der-letzte-eintrag/1786828#m1786828 <p>Hi Rolf,</p> <blockquote> <p>SQL kann überraschend einfach sein, und auch überraschend komplex. Man muss komplexe Queries in ihre Teile gliedern.</p> </blockquote> <p>Habe ich versucht. Die verflixten Klammern warens, die mich irritiert haben.</p> <blockquote> <blockquote> <p>Ist irgendwie, wie beim Ostereier suchen. Da war ich auch nie sonderlich gut drin </p> </blockquote> <p>Wenn Du damit meinst, dass Du mit Geduld und strukturiertem Vorgehen ein Problem hast, dann ist deine Zukunft in der Computerwelt sehr steinig.</p> </blockquote> <p>Wem sagst Du es? </p> <blockquote> <p>Zugegeben, nachher sieht die Query merkwürdig aus, sie scheint dann zweimal nacheinander das gleiche abzufragen.</p> </blockquote> <pre><code class="block">... AND XYZ = 1) AND XYZ = 1) OR ... </code></pre> <p>Finde ich weniger irritierend als die boolsche Optimierung zu "übersehen", ist aber Geaschacksache.</p> <p>Danke für Deine Hilfe </p> <p>Jörg</p> mysql, Query, Immer nur der letzte Eintrag Sat, 03 Apr 21 10:10:26 Z https://forum.selfhtml.org/self/2021/apr/02/mysql-query-immer-nur-der-letzte-eintrag/1786835#m1786835 https://forum.selfhtml.org/self/2021/apr/02/mysql-query-immer-nur-der-letzte-eintrag/1786835#m1786835 <p>Hallo Jörg,</p> <blockquote> <p>Die verflixten Klammern warens, die mich irritiert haben.</p> </blockquote> <p>Ja, ein bisschen Talent für <a href="https://de.wikipedia.org/wiki/Lisp" rel="nofollow noopener noreferrer">LISP</a><sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup> braucht es in jeder Sprache.</p> <p><em>Rolf</em></p> <div class="signature">-- <br> sumpsi - posui - obstruxi </div> <hr class="footnotes-sep"> <section class="footnotes"> <ol class="footnotes-list"> <li id="fn1" class="footnote-item"><p>LISP - Lots of Irritating Superfluous Parentheses <a href="#fnref1" class="footnote-backref">↩︎</a></p> </li> </ol> </section> mysql, Query, Immer nur der letzte Eintrag Sat, 03 Apr 21 10:16:01 Z https://forum.selfhtml.org/self/2021/apr/02/mysql-query-immer-nur-der-letzte-eintrag/1786837#m1786837 https://forum.selfhtml.org/self/2021/apr/02/mysql-query-immer-nur-der-letzte-eintrag/1786837#m1786837 <p>Hallo Rolf,</p> <blockquote></blockquote> <p>Genau an diese Übersetzung von LISP ,musste ich auch sofort denken </p> <p>Mein Editor zeigt mir ja normalerweise matching brackets an, leider aber nicht im sql-Teil des php. </p> <p>Jörg</p>