tag:forum.selfhtml.org,2005:/self mysql - 2 Queries oder doch eine? – SELFHTML-Forum 2021-03-19T16:15:48Z https://forum.selfhtml.org/self/2021/mar/19/mysql-2-queries-oder-doch-eine/1786001#m1786001 Jörg 2021-03-19T10:12:44Z 2021-03-19T10:12:44Z mysql - 2 Queries oder doch eine? <p>Guten Tag,</p> <p>ich fange mal direkt mit der Query an und versuche meine Frage daran entlang zu hangeln.</p> <pre><code class="block language-sql"><span class="token keyword">SELECT</span> m<span class="token punctuation">.</span>ID<span class="token punctuation">,</span> usw<span class="token punctuation">.</span> <span class="token keyword">FROM</span> table1 m <span class="token keyword">LEFT</span> <span class="token keyword">JOIN</span> table2 dg <span class="token keyword">ON</span> m<span class="token punctuation">.</span>ID <span class="token operator">=</span> dg<span class="token punctuation">.</span>ID <span class="token keyword">LEFT</span> <span class="token keyword">JOIN</span> table3 s <span class="token keyword">ON</span> s<span class="token punctuation">.</span>ID <span class="token operator">=</span> m<span class="token punctuation">.</span>ID <span class="token keyword">LEFT</span> <span class="token keyword">JOIN</span> table4 mn <span class="token keyword">ON</span> mn<span class="token punctuation">.</span>MID <span class="token operator">=</span> s<span class="token punctuation">.</span>MID <span class="token keyword">WHERE</span> m<span class="token punctuation">.</span>ID <span class="token operator">IN</span><span class="token punctuation">(</span><span class="token number">1094</span><span class="token punctuation">,</span><span class="token number">1095</span><span class="token punctuation">)</span> <span class="token operator">AND</span> m<span class="token punctuation">.</span>Del <span class="token operator">!=</span> <span class="token number">1</span> <span class="token operator">AND</span> dg<span class="token punctuation">.</span>del <span class="token operator">!=</span> <span class="token number">1</span> <span class="token operator">AND</span> mn<span class="token punctuation">.</span>MID <span class="token operator">=</span> <span class="token number">4780</span> </code></pre> <p>Eigentlich benötige ich alle IDs + "Zubehör", die ich bereits habe (1094,1095). Ich hätte gerne lediglich zusätzlich aus den anderen Tabellen weitere Infos, sofern die restlichen 3 WHERE-Klauseln (alle 3) ebenfalls erfüllt sind.</p> <p>Die Grundangaben aus Tabelle1 benötige ich zu 1094 und 1095 aber auf jeden Fall.</p> <p>Dieses mit 2 Queries zu ermitteln, ist nicht meine Frage, das bekomme ich schon hin. Ich versuche gerade, das in einer einzigen Query sinnvoll zu ermitteln.</p> <p>Geht das und wenn ja, wie (UNION mal außen vor gelassen)?</p> <p>Gruß, Jörg</p> https://forum.selfhtml.org/self/2021/mar/19/mysql-2-queries-oder-doch-eine/1786003#m1786003 Rolf B 2021-03-19T10:22:46Z 2021-03-19T10:29:03Z mysql - 2 Queries oder doch eine? <p>Hallo Jörg,</p> <p>d.h. wenn m.Del den Wert 1 hat, kannst Du auf alle drei LEFT JOIN Ergebnisse verzichten, brauchst aber die Werte aus der m-Tabelle trotzdem?</p> <p>WHERE wirkt auf das Ergebnis des JOIN, und ON wirkt auf die zugeJOINte Table. Probier's mal so:</p> <pre><code class="block language-sql"><span class="token keyword">SELECT</span> m<span class="token punctuation">.</span>ID<span class="token punctuation">,</span> usw<span class="token punctuation">.</span> <span class="token keyword">FROM</span> table1 m <span class="token keyword">LEFT</span> <span class="token keyword">JOIN</span> table2 dg <span class="token keyword">ON</span> m<span class="token punctuation">.</span>Del <span class="token operator">!=</span> <span class="token number">1</span> <span class="token operator">AND</span> dg<span class="token punctuation">.</span>ID <span class="token operator">=</span> m<span class="token punctuation">.</span>ID <span class="token operator">AND</span> dg<span class="token punctuation">.</span>del <span class="token operator">!=</span> <span class="token number">1</span> <span class="token keyword">LEFT</span> <span class="token keyword">JOIN</span> table3 s <span class="token keyword">ON</span> m<span class="token punctuation">.</span>Del <span class="token operator">!=</span> <span class="token number">1</span> <span class="token operator">AND</span> s<span class="token punctuation">.</span>ID <span class="token operator">=</span> m<span class="token punctuation">.</span>ID <span class="token keyword">LEFT</span> <span class="token keyword">JOIN</span> table4 mn <span class="token keyword">ON</span> m<span class="token punctuation">.</span>Del <span class="token operator">!=</span> <span class="token number">1</span> <span class="token operator">AND</span> mn<span class="token punctuation">.</span>MID <span class="token operator">=</span> s<span class="token punctuation">.</span>MID <span class="token operator">AND</span> mn<span class="token punctuation">.</span>MID <span class="token operator">=</span> <span class="token number">4780</span> <span class="token keyword">WHERE</span> m<span class="token punctuation">.</span>ID <span class="token operator">IN</span><span class="token punctuation">(</span><span class="token number">1094</span><span class="token punctuation">,</span><span class="token number">1095</span><span class="token punctuation">)</span> </code></pre> <p>Man müsste Explains laufen lassen, um zu prüfen, ob die Reihenfolge der Abfragen im ON eine Relevanz für den Query-Plan hat oder ob die DB das sinnvoll optimiert. Zumindest im dritten LEFT JOIN wäre es nämlich sinnvoll, bei s.MID != 4780 gar nicht erst die Tabelle anzugucken, und wenn der Server strikt von links nach rechts abfragt, wäre<br> <code>ON m.Del != 1 AND s.MID = 4780 AND mn.MID = s.MID</code><br> wohl performanter. Das kann man aber vermutlich nur mit einer großen DB und einer wilden Abfrage auf zufällige Daten wirklich feststellen.</p> <p><em>Rolf</em></p> <div class="signature">-- <br> sumpsi - posui - obstruxi </div> https://forum.selfhtml.org/self/2021/mar/19/mysql-2-queries-oder-doch-eine/1786004#m1786004 Jörg 2021-03-19T10:36:10Z 2021-03-19T10:36:10Z mysql - 2 Queries oder doch eine? <p>Hallo Rolf,</p> <blockquote> <p>d.h. wenn m.Del den Wert 1 hat, kannst Du auf alle drei LEFT JOIN Ergebnisse verzichten, brauchst aber die Werte aus der m-Tabelle trotzdem?</p> </blockquote> <p>Nein, dann würde ich sowohl die m-Werte als auch die restlichen benötigen. Lediglich wenn es in der dg-Tabelle zur m.ID dann keinen Eintrag gibt, könnte ich in diesem Fall auf sämtliche Werte (t1-t4) verzichten.</p> <p>Gruß, Jörg</p> https://forum.selfhtml.org/self/2021/mar/19/mysql-2-queries-oder-doch-eine/1786006#m1786006 Rolf B 2021-03-19T10:39:34Z 2021-03-19T10:39:34Z mysql - 2 Queries oder doch eine? <p>Hallo Jörg,</p> <p>lies nochmal was ich schrieb oder erkläre mir meinen Denkfehler. Aus meiner Sicht passt dies</p> <blockquote> <blockquote> <p>wenn m.Del den Wert 1 hat</p> </blockquote> </blockquote> <blockquote> <p>... dann würde ich sowohl die m-Werte als auch die restlichen benötigen.</p> </blockquote> <p>und das</p> <pre><code class="block language-sql"> <span class="token keyword">WHERE</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> <span class="token operator">AND</span> m<span class="token punctuation">.</span>Del <span class="token operator">!=</span> <span class="token number">1</span> <span class="token operator">AND</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> </code></pre> <p>nicht zusammen.</p> <p><em>Rolf</em></p> <div class="signature">-- <br> sumpsi - posui - obstruxi </div> https://forum.selfhtml.org/self/2021/mar/19/mysql-2-queries-oder-doch-eine/1786008#m1786008 Jörg 2021-03-19T10:57:30Z 2021-03-19T11:00:03Z mysql - 2 Queries oder doch eine? <p>Hallo Rolf,</p> <blockquote> <p>lies nochmal was ich schrieb oder erkläre mir meinen Denkfehler. Aus meiner Sicht passt dies</p> </blockquote> <p>Nein, Du hast keinen Denkfehler. Es beschreibt meine Frage, die ich aber schwer in Worte fassen kann.</p> <p>ich versuchs aber noch mal:</p> <p>Ich habe Tabelle 1, aus der ich Grundwerte eines Artikels benötige. Für jeden dieser Artikel kann in Tabelle 4 ein Vorgang erzeugt werden. Da aber auch mehrere Artikel in einen Vorgang übernommen werden können, werden die Artikel über Tabelle 3 dem Vorgang zugeordnet. Nun können in Tabelle 2 je Artikel aber auch ganz andere Vorgänge erzeugt werden.</p> <p>An dieser Stelle stehe ich nun. Der User ruft ein Interface (für den Vorgang / Tabelle 2) auf und soll alle dem Vorgang zugeordnete Artikel angezeigt bekommen und darüber hinaus auch die Tabelle2-Vorgänge, die bereits angelegt sind.</p> <p>Sollte ein Artikel inzwischen gelöscht sein (m.del=1), dafür aber bereits ein Tabelle2-Vorgang existent, soll dieser trortdem ganz normal angezeit werden. Existiert kein Tabelle2-Vorgang, dann wirde auch der rest des "m.del=1-Artikels" nicht angezeigt.</p> <p>Ich hoffe, ich habe in der Geschichte keine Unlogik eingebaut, da sie nicht ganz der Realität entspricht, aber im Großen und Ganzen sollte es ganz gut beschrieben, was ich meine. Falls nicht, bitte gerne nachfragen.</p> <p>Gruß, Jörg</p> https://forum.selfhtml.org/self/2021/mar/19/mysql-2-queries-oder-doch-eine/1786019#m1786019 Rolf B 2021-03-19T12:40:42Z 2021-03-19T12:40:42Z mysql - 2 Queries oder doch eine? <p>Hallo Jörg,</p> <blockquote> <p>Ich hoffe, ich habe in der Geschichte keine Unlogik eingebaut</p> </blockquote> <p>Ich verstehe sie nicht.</p> <p>Aus deinen Beschreibungen lese ich dieses Datenmodell heraus (erstellt mit dbdiagram.io):</p> <p><img src="/images/5317ae04-88ae-11eb-ab43-b42e9947ef30.png?size=medium" alt="" loading="lazy"></p> <p>Ist das so richtig? Insbesondere die Kardinalitäten? Du beschreibst zwischen Table1 und Table4 eine m:n Beziehung und verwendest sie auch in der Query. Table1 scheint aber zu Table2 in einer 1:n Beziehung zu stehen.</p> <p>Insbesondere komme ich nicht damit klar, warum table2 und table4 Vorgänge enthalten und warum table4 überhaupt in der Query ist, wenn doch der User Vorgänge aus Table2 auswählt und die weiteren Vorgänge auch nur aus Table2 kommen sollen.</p> <p>Und dann das hier:</p> <blockquote> <p>Sollte ein Artikel inzwischen gelöscht sein (m.del=1), dafür aber bereits ein Tabelle2-Vorgang existent, soll <strong>dieser</strong> trortdem ganz normal angezeit werden.</p> </blockquote> <p>Error: duplicate reference at rolfb.cmd:34677642<sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup></p> <p>Ich will damit fragen, ob das fett gesetzte <strong>dieser</strong> der Artikel oder der Vorgang ist.</p> <p>Aber wie auch immer - ich würde bezweifeln, dass es sinnvoll ist, all das in eine JOIN Query zu packen. Durch die Joins entstehen jede Menge Kombinationen zwischen Artikeln und Vorgängen, so dass Du nachher - mutmaßlich - jede Menge redundante Daten im Ergebnis hast die Du dann im Programmcode wieder deduplizieren musst. Ein UNION ist auch so eine Sache, du kannst nicht Artikel und Vorgänge mit UNION zusammenpacken, weil ein Union strukturelle Gleichheit vorausetzt.</p> <p>Wenn Du vom User eine Vorgangs-ID als Einstieg bekommts, wären zwei bis drei Queries vermutlich besser. Die erste bestimmt die Artikel zum Vorgang, und die zweite alle Vorgänge, die mit diesen Artikeln in Beziehung stehen. Ob der zweite Schritt in einer Query oder in zweien gemacht werden muss, hängt davon ab, ob table2 und table4 strukturgleich sind. Wenn ja, kann man einen UNION machen. Wenn nein, kann man es vielleicht geschickt zusammenfügen. Vielleicht.</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>Abgeleitet von: Für die einen ist es Windows, für die anderen die größte und langsamste Batchdatei der Welt <a href="#fnref1" class="footnote-backref">↩︎</a></p> </li> </ol> </section> https://forum.selfhtml.org/self/2021/mar/19/mysql-2-queries-oder-doch-eine/1786022#m1786022 Jörg 2021-03-19T13:11:03Z 2021-03-19T13:11:03Z mysql - 2 Queries oder doch eine? <p>Hallo Rolf,</p> <blockquote> <blockquote> <p>Ich hoffe, ich habe in der Geschichte keine Unlogik eingebaut</p> </blockquote> <p>Ich verstehe sie nicht.</p> </blockquote> <p>Liegt an mir, resp. meiner Erklärung </p> <blockquote> <p>Aus deinen Beschreibungen lese ich dieses Datenmodell heraus (erstellt mit dbdiagram.io):</p> <p><img src="/images/5317ae04-88ae-11eb-ab43-b42e9947ef30.png?size=medium" alt="" loading="lazy"></p> </blockquote> <p>Haut hin.</p> <blockquote> <p>Ist das so richtig? Insbesondere die Kardinalitäten? Du beschreibst zwischen Table1 und Table4 eine m:n Beziehung und verwendest sie auch in der Query. Table1 scheint aber zu Table2 in einer 1:n Beziehung zu stehen.</p> </blockquote> <p>Stell Dir einfach vor, dass der User eine Art Warenkorb (Tabelle 4) mit Artikeln (Tabelle 1) füllt (über Tabelle 3 zusammengefasst). Nun kann er zudem zu jedem Artikel ein (wie und was auch immer geartetes) Protokol (Tabelle 2) anlegen.</p> <blockquote> <p>Insbesondere komme ich nicht damit klar, warum table2 und table4 Vorgänge enthalten und warum table4 überhaupt in der Query ist, wenn doch der User Vorgänge aus Table2 auswählt und die weiteren Vorgänge auch nur aus Table2 kommen sollen.</p> </blockquote> <p>Nein, der User befindet sich im Warenkorb und will einen Protokollvorgang zu einem (oder mehreren) Artikel(n) erstellen.</p> <p>Und genau hier möchte ich ihm alle Artikel auflisten, die der Warenkorb enthält, aber auch alle bereits angelegten Protokolle.</p> <blockquote> <p>Und dann das hier:</p> <blockquote> <p>Sollte ein Artikel inzwischen gelöscht sein (m.del=1), dafür aber bereits ein Tabelle2-Vorgang existent, soll <strong>dieser</strong> trortdem ganz normal angezeit werden.</p> </blockquote> </blockquote> <p>Damit ist gemeint, dass wenn der Artikel aus dem Programm gestrichen ist, will ich zuvor angelegte Warenkörbe inkl. diesem Artikel und der Protokolle für diesen Artikel behalten und auch anzeigen.</p> <blockquote> <p>Wenn Du vom User eine Vorgangs-ID als Einstieg bekommts, wären zwei bis drei Queries vermutlich besser. Die erste bestimmt die Artikel zum Vorgang, und die zweite alle Vorgänge, die mit diesen Artikeln in Beziehung stehen.</p> </blockquote> <p>Ich fürchte auch, dass ich es splitten muss. Schade, schön wärs gewesen, wenn das elegant über eine einzige Query hätte erledigt werden können.</p> <p>Danke fürs Mitdenken auf jeden Fall,</p> <p>Jörg</p> https://forum.selfhtml.org/self/2021/mar/19/mysql-2-queries-oder-doch-eine/1786023#m1786023 Rolf B 2021-03-19T13:13:35Z 2021-03-19T13:14:40Z mysql - 2 Queries oder doch eine? <p>Hallo Jörg,</p> <p>d.h. Warenkörbe und <s>Artikelbewertungen</s> Protokolle sind strukturell sehr verschieden.</p> <p>Klingt nach 3 Queries.</p> <p><em>Rolf</em></p> <div class="signature">-- <br> sumpsi - posui - obstruxi </div> https://forum.selfhtml.org/self/2021/mar/19/mysql-2-queries-oder-doch-eine/1786024#m1786024 Der Martin 2021-03-19T13:17:59Z 2021-03-19T13:17:59Z mysql - 2 Queries oder doch eine? <p>Hallo Jörg,</p> <blockquote> <p>der User befindet sich im Warenkorb</p> </blockquote> <p>das stelle ich mir sehr originell vor. Eventuell ein bisschen eng. </p> <p>Live long and <s>pros</s> healthy,<br>  Martin</p> <div class="signature">-- <br> Wer respektiert werden will, sollte zunächst damit anfangen, andere zu respektieren. </div> https://forum.selfhtml.org/self/2021/mar/19/mysql-2-queries-oder-doch-eine/1786027#m1786027 Jörg 2021-03-19T14:23:01Z 2021-03-19T14:23:01Z mysql - 2 Queries oder doch eine? <p>Hallo Rolf,</p> <blockquote> <p>d.h. Warenkörbe und <s>Artikelbewertungen</s></p> </blockquote> <p>schöne Analogie, hätt' ich selber drauf kommen können/sollen :D</p> <p>Aber wiese 3 Queries?</p> <ol> <li>Artikel im Warenkorb auflisten</li> <li>Bewertung je Artikel, falls vorhanden</li> <li>???</li> </ol> <p>Jörg</p> https://forum.selfhtml.org/self/2021/mar/19/mysql-2-queries-oder-doch-eine/1786031#m1786031 Rolf B 2021-03-19T14:54:13Z 2021-03-19T14:54:13Z mysql - 2 Queries oder doch eine? <p>Hallo Martin,</p> <p>sowas seh ich regelmäßig im Supermarkt.</p> <p><em>Rolf</em></p> <div class="signature">-- <br> sumpsi - posui - obstruxi </div> https://forum.selfhtml.org/self/2021/mar/19/mysql-2-queries-oder-doch-eine/1786030#m1786030 Rolf B 2021-03-19T14:53:30Z 2021-03-19T14:53:30Z mysql - 2 Queries oder doch eine? <p>Hallo Jörg,</p> <p>ich dachte an Vorgänge. Aber da bin ich dann wohl mit deiner Doppelbelegung des Begriffs für table2 und table4 durcheinander gekommen.</p> <p>Den Warenkorb selbst wirst Du aber auch brauchen, oder?</p> <p>Also</p> <pre><code class="block language-sql"><span class="token comment">-- Allg. Daten zum Warenkorb einlesen</span> <span class="token keyword">SELECT</span> w<span class="token punctuation">.</span>mid<span class="token punctuation">,</span> w<span class="token punctuation">.</span>foo<span class="token punctuation">,</span> w<span class="token punctuation">.</span>bar<span class="token punctuation">,</span> w<span class="token punctuation">.</span>baz <span class="token keyword">FROM</span> table4 w <span class="token keyword">WHERE</span> w<span class="token punctuation">.</span>mid <span class="token operator">=</span> <span class="token number">4780</span> <span class="token comment">-- Artikel im Warenkorb holen</span> <span class="token keyword">SELECT</span> s<span class="token punctuation">.</span>anzahl<span class="token punctuation">,</span> s<span class="token punctuation">.</span>dings<span class="token punctuation">,</span> s<span class="token punctuation">.</span>bums<span class="token punctuation">,</span> a<span class="token punctuation">.</span>id<span class="token punctuation">,</span> a<span class="token punctuation">.</span>name<span class="token punctuation">,</span> a<span class="token punctuation">.</span>del<span class="token punctuation">,</span> foo<span class="token punctuation">,</span> bar<span class="token punctuation">,</span> baz <span class="token keyword">FROM</span> table3 s <span class="token keyword">JOIN</span> artikel a <span class="token keyword">ON</span> s<span class="token punctuation">.</span>id <span class="token operator">=</span> a<span class="token punctuation">.</span>id <span class="token keyword">WHERE</span> s<span class="token punctuation">.</span>mid <span class="token operator">=</span> <span class="token number">4780</span> </code></pre> <p>An dieser Stelle solltest Du die Artikelliste übernehmen und die Artikel-IDs zu einer kommaseparierten Liste machen</p> <pre><code class="block language-sql"><span class="token keyword">SELECT</span> dg<span class="token punctuation">.</span>id<span class="token punctuation">,</span> dg<span class="token punctuation">.</span>bla<span class="token punctuation">,</span> dg<span class="token punctuation">.</span>blub<span class="token punctuation">,</span> dg<span class="token punctuation">.</span>hui <span class="token keyword">FROM</span> table2 dg <span class="token keyword">WHERE</span> dg<span class="token punctuation">.</span>id <span class="token operator">IN</span> <span class="token punctuation">(</span>$artikelliste<span class="token punctuation">)</span> </code></pre> <p>$artikelliste in den SQL String zu setzen wäre PHP - ich weiß nicht welche Sprache Du verwendest. Maskieren ist hier nicht erforderlich, wenn die aus der Artikeltabelle gelesenen IDs numerisch sind. An welchen Stellen Du noch auf das <code>del</code> Kennzeichen abfragen musst, ist mir nicht so klar.</p> <p>Eine IN Klausel hat den Nachteil, dass man die Werte darin nicht per Prepare einsteuern kann. Also jedenfalls nicht als Array, man müsste für jeden Wert einen eigenen Parametermarker verwenden und das ist Quatsch, wenn die Anzahl variabel ist. Die Alternative zum dynamisch aufgebauten SQL String wäre eine Subquery, die die Artikel-IDs liefert. Dafür reicht table3. Das sollte fix genug sein, denn die Daten sollten dann noch im Cache liegen. Ob es für Dich schnell genug ist, musst Du testen. Die reine SQL Performance ist nicht allein entscheidend, denn die Host-Programmiersprache muss ja im anderen Fall auch den Id-String aufbauen und das SQL Statement muss neu geparsed werden.</p> <pre><code class="block language-sql"><span class="token keyword">SELECT</span> dg<span class="token punctuation">.</span>id<span class="token punctuation">,</span> dg<span class="token punctuation">.</span>bla<span class="token punctuation">,</span> dg<span class="token punctuation">.</span>blub<span class="token punctuation">,</span> dg<span class="token punctuation">.</span>hui <span class="token keyword">FROM</span> table2 dg <span class="token keyword">WHERE</span> dg<span class="token punctuation">.</span>id <span class="token operator">IN</span> <span class="token punctuation">(</span><span class="token keyword">SELECT</span> s<span class="token punctuation">.</span>id <span class="token keyword">FROM</span> table3 s <span class="token keyword">WHERE</span> s<span class="token punctuation">.</span>mid <span class="token operator">=</span> <span class="token number">4780</span><span class="token punctuation">)</span> </code></pre> <p><em>Rolf</em></p> <div class="signature">-- <br> sumpsi - posui - obstruxi </div> https://forum.selfhtml.org/self/2021/mar/19/mysql-2-queries-oder-doch-eine/1786040#m1786040 Jörg 2021-03-19T15:25:54Z 2021-03-19T15:27:31Z mysql - 2 Queries oder doch eine? <p>Hallo Rolf,</p> <blockquote> <p>Den Warenkorb selbst wirst Du aber auch brauchen, oder?</p> </blockquote> <p>Jain, denn dort ist der Ausgangspunkt. Er ist insofern vorhanden. Auch $artikelliste ist bereits vorhanden, weil als Funktion hinterlegt und bereits an dieser Stelle im Programm genutzt.</p> <blockquote> <p>Also</p> <pre><code class="block language-sql"><span class="token comment">-- Allg. Daten zum Warenkorb einlesen</span> <span class="token keyword">SELECT</span> w<span class="token punctuation">.</span>mid<span class="token punctuation">,</span> w<span class="token punctuation">.</span>foo<span class="token punctuation">,</span> w<span class="token punctuation">.</span>bar<span class="token punctuation">,</span> w<span class="token punctuation">.</span>baz <span class="token keyword">FROM</span> table4 w <span class="token keyword">WHERE</span> w<span class="token punctuation">.</span>mid <span class="token operator">=</span> <span class="token number">4780</span> <span class="token comment">-- Artikel im Warenkorb holen</span> <span class="token keyword">SELECT</span> s<span class="token punctuation">.</span>anzahl<span class="token punctuation">,</span> s<span class="token punctuation">.</span>dings<span class="token punctuation">,</span> s<span class="token punctuation">.</span>bums<span class="token punctuation">,</span> a<span class="token punctuation">.</span>id<span class="token punctuation">,</span> a<span class="token punctuation">.</span>name<span class="token punctuation">,</span> a<span class="token punctuation">.</span>del<span class="token punctuation">,</span> foo<span class="token punctuation">,</span> bar<span class="token punctuation">,</span> baz <span class="token keyword">FROM</span> table3 s <span class="token keyword">JOIN</span> artikel a <span class="token keyword">ON</span> s<span class="token punctuation">.</span>id <span class="token operator">=</span> a<span class="token punctuation">.</span>id <span class="token keyword">WHERE</span> s<span class="token punctuation">.</span>mid <span class="token operator">=</span> <span class="token number">4780</span> </code></pre> <p>An dieser Stelle solltest Du die Artikelliste übernehmen und die Artikel-IDs zu einer kommaseparierten Liste machen</p> <pre><code class="block language-sql"><span class="token keyword">SELECT</span> dg<span class="token punctuation">.</span>id<span class="token punctuation">,</span> dg<span class="token punctuation">.</span>bla<span class="token punctuation">,</span> dg<span class="token punctuation">.</span>blub<span class="token punctuation">,</span> dg<span class="token punctuation">.</span>hui <span class="token keyword">FROM</span> table2 dg <span class="token keyword">WHERE</span> dg<span class="token punctuation">.</span>id <span class="token operator">IN</span> <span class="token punctuation">(</span>$artikelliste<span class="token punctuation">)</span> </code></pre> </blockquote> <p>Nicht bös sein, aber ich glaube, so wird das eher nichts. Du hast die Daten aus Tabelle1 unberücksichtigt, die sind aber wichtig (oder meintest Du das mit Deiner Eingangsfrage nach dem Warenkorb?).</p> <p>Meine Idee:</p> <pre><code class="block">Query 1: (ermittelt die Artikel) SELECT m.t1_id, m.bla, m.blub, m.hui FROM table1 m JOIN table3 t3 ON m.t1_id = t3.t1_id WHERE t3.mid = 4780 AND m.del != 1 Query 2: (ermittelt die Artikelbewertungen) SELECT dg.t2_id, dg.bla, dg.blub, dg.hui FROM table 1 m LEFT JOIN table2 dg ON m.t1_id = dg.t1_id WHERE dg.t1_id IN ($artikelliste) AND dg.del != 1 </code></pre> <p>Was mir noch fehlt, ist der Zusammenhang aus Query1+2, also die Zuordnung der Bewertungen zum Artikel.</p> <p>Jörg</p> https://forum.selfhtml.org/self/2021/mar/19/mysql-2-queries-oder-doch-eine/1786042#m1786042 Rolf B 2021-03-19T15:58:04Z 2021-03-19T15:58:04Z mysql - 2 Queries oder doch eine? <p>Hallo Jörg,</p> <blockquote> <p>Nicht bös sein, aber ich glaube, so wird das eher nichts. Du hast die Daten aus Tabelle1 unberücksichtigt,</p> </blockquote> <p>Nee, hab ich berücksichtigt, nur habe ich die Tabelle unachtsamerweise <code>artikel</code> statt <code>table1</code> genannt. Steht doch drüber: „Artikel im Warenkorb holen“.</p> <p>Deine Query1 tut das, was meine Query auch tut, ich hab nur noch ein paar Daten aus der table3 dazugepinnt (was einem Warenkorb entspricht: 7 Unterhosen, 9 Socken, etc) - aber da deine Daten mutmaßlich ganz anders aussehen, ist das reiner Spekulatius zu Ostern.</p> <p>Der Unterschied ist nur, dass Du m.del in der Where Bedingung hast, d.h. du liest gelöschte Artikel nicht mit. Aber sagtest Du nicht, dass Du die trotz Löschung mit lesen wolltest?</p> <p>Beim Lesen der Artikelbewertungen brauchst Du table1 nicht, wenn Du die benötigten IDs in der Artikelliste hast. Du machst einen JOIN von table1 und table2, verwendest aber keine Daten aus table1. Weder im SELECT noch im WHERE. Wozu also Joinen? Allerdings hast Du da ein bisschen an den Spaltennamen rumgemacht, das war vorher anders. Du hast jetzt t1_id und t2_id - ist das die Artikel-ID und die Bewertungs-ID? Dann solltest Du dg.t1_id mit selektieren.</p> <p>Wenn Du das gemacht hast, kannst Du</p> <ul> <li>das Array mit Artikeln im PHP über die Artikel-ID schlüsseln</li> <li>für jede gefundene Bewertung den Artikel-Eintrag rausholen und die Bewertung dort an eine Bewertungen-Array anpappen.</li> </ul> <pre><code class="block language-php"><span class="token variable">$warenkorbinhalt</span> <span class="token operator">=</span> <span class="token keyword">ARRAY</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">/* SQL Query 1 ausführen */</span> <span class="token keyword">while</span> <span class="token punctuation">(</span><span class="token variable">$artikel</span> <span class="token operator">=</span> <span class="token comment">/* row holen, z.B. mysqli_fetch_assoc */</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$artikel</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'bewertungen'</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token keyword">ARRAY</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Array für Bewertungen vorbereiten</span> <span class="token variable">$warenkorbinhalt</span><span class="token punctuation">[</span><span class="token variable">$artikel</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'t1_id'</span><span class="token punctuation">]</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token variable">$artikel</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/* $artikelliste aufbauen */</span> <span class="token comment">/* SQL Query 2 ausführen */</span> <span class="token keyword">while</span> <span class="token punctuation">(</span><span class="token variable">$bewertung</span> <span class="token operator">=</span> <span class="token comment">/* row holen */</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$artikel</span> <span class="token operator">=</span> <span class="token variable">$warenkorbinhalt</span><span class="token punctuation">[</span><span class="token variable">$bewertung</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'t1_id'</span><span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token variable">$artikel</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'bewertungen'</span><span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token variable">$bewertung</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> </code></pre> <p>Fertig. Und das gibst Du dann so, wie Du es brauchst, als HTML aus.</p> <p><em>Rolf</em></p> <div class="signature">-- <br> sumpsi - posui - obstruxi </div> https://forum.selfhtml.org/self/2021/mar/19/mysql-2-queries-oder-doch-eine/1786044#m1786044 Jörg 2021-03-19T16:15:48Z 2021-03-19T16:16:14Z mysql - 2 Queries oder doch eine? <p>Hallo Rolf,</p> <blockquote> <p>Nee, hab ich berücksichtigt, nur habe ich die Tabelle unachtsamerweise <code>artikel</code> statt <code>table1</code> genannt. Steht doch drüber: „Artikel im Warenkorb holen“.</p> </blockquote> <p>Stimmt. Nehme alles zurück und behaupte fortan das Gegentum </p> <blockquote> <p>Deine Query1 tut das, was meine Query auch tut, ich hab nur noch ein paar Daten aus der table3 dazugepinnt (was einem Warenkorb entspricht: 7 Unterhosen, 9 Socken, etc) - aber da deine Daten mutmaßlich ganz anders aussehen, ist das reiner Spekulatius zu Ostern.</p> </blockquote> <p>Ja. T3 ist eine reine Zuordnungstabelle (t1_id, t5_id).</p> <blockquote> <p>Der Unterschied ist nur, dass Du m.del in der Where Bedingung hast, d.h. du liest gelöschte Artikel nicht mit. Aber sagtest Du nicht, dass Du die trotz Löschung mit lesen wolltest?</p> </blockquote> <p>In der ersten Query muss es mit hinein, weil ich ansonsten Artikel aufliste, die ausgelistet sind. Es sollen nur die Bewertungen angezeigt werden, nicht die Artikel selber. Hört sich erstmal doof an, ist aber schlußendlich logisch, wenn man die (viel zu kompliziert zu erklärende RL-Lösung kennt)</p> <blockquote> <p>Beim Lesen der Artikelbewertungen brauchst Du table1 nicht, wenn Du die benötigten IDs in der Artikelliste hast. Du machst einen JOIN von table1 und table2, verwendest aber keine Daten aus table1. Weder im SELECT noch im WHERE. Wozu also Joinen?</p> </blockquote> <p>Sorry, ich muss hier joinen, weil die Query verkürzt ist, ich aber "in Echt" doch auch noch Daten aus T1 brauche.</p> <blockquote> <p>Allerdings hast Du da ein bisschen an den Spaltennamen rumgemacht, das war vorher anders. Du hast jetzt t1_id und t2_id - ist das die Artikel-ID und die Bewertungs-ID? Dann solltest Du dg.t1_id mit selektieren.</p> </blockquote> <p>Ich habe das extra gemacht, damit die Zuordnungen der Tabellen zueinander und die vorhandenen Spalten in den Tabellen klarer werden.</p> <blockquote> <p>Wenn Du das gemacht hast, kannst Du</p> <ul> <li>das Array mit Artikeln im PHP über die Artikel-ID schlüsseln</li> <li>für jede gefundene Bewertung den Artikel-Eintrag rausholen und die Bewertung dort an eine Bewertungen-Array anpappen....</li> </ul> </blockquote> <blockquote> <p>Fertig. Und das gibst Du dann so, wie Du es brauchst, als HTML aus.</p> </blockquote> <p>Stimmt, das muss dann php übernehmen.</p> <p>Danke für Deine Hilfe und Grüße,</p> <p>Jörg</p>