View Full Version : SQL join mit nur letztem Satz
... imho sind ANSI konforme Konstrukte vorzuziehen und die einfachste, am besten lesbare Variante ist am besten. Wenn dann eine Variante langsamer ist, taugt der Optimizer nichts. Am Rande sei noch vermerkt, dass komplizierte SQL Statements auch ein Zeichen für lausiges Datenbankdesign sein könnten.
Der Griff nach KI ist meist ein Zeichen von Mangel an NI oder Faulheit - kann aber nach umgekehrtem Eiffelturm-Prinzip durchaus Karriere-fördernd sein.
D*B
Ich habe mir nun mal die Mühe gemacht, den Explain mi den SQL's zu prüfen:
left join Lateral mit where order by limit
führt zu
Index Probe => Table Probe => Fetch n Rows => nested Loop Join
left join CTE mit On-Klausel führt zu
Index Probe => Table Probe => Aggregation => nested Loop
Der Unterschied ist, dass nach dem Lateral nur noch ein Fetch einer Zeile passiert, während bei dem Grouped-Join noch ein Aggregat gebildet werden muss, was durchaus mehr als 1 Zeile umfassen kann.
Gegen den CTE spricht ebenso, dass ich einen 2. Left join mit dem CTE benötige, wenn ich weitere Werte aus dem Satz haben muss.
Das funktioniert halt nicht mit dem CTE, da ich hier einen Group By benötige um Aggregate verwenden zu können.
Dies führt dann zu einem 2. Index Probe => Table Probe => nested Loop
Wie du an meinem Lateral siehst, benötige ich nur ein b.* um aus dem Lateral alles zu erhalten, was ich benötige.
Ein weiteres Argument gegen CTE's ist leider auch, dass ich diese nicht in einem Insert oder Merge verwenden kann, sondern hier auf derived Table gehen muss.
Es gibt aber noch eine weitere Anwendung für lateral.
Wer kennt nicht die Tabellen mit pseudo Array-Feldern, die durchnummeriert sind.
Bisher musste man diese mit einem etwas kompexeren union all trennen um sie per SQL vernünftig zu verarbeiten:
select artikel, menge01 as menge from myfile
union all
select artikel, menge02 as menge from myfile
:
Dies führt dann zu n * Indexscan => Table Probe => union all
Mit Lateral ist das nun erheblich einfacher:
select artikel, x.* from myfile
cross join lateral (
values(menge01)
union all
values(menge02)
) x (menge)
Dies führt zu n * values list => union all => nested loop
Außerdem gehört Lateral bei vielen anderen DBM's inzwischen zum Standard.
Wer mehr wissen will:
https://medium.com/@goldengrisha/a-deep-dive-into-sql-lateral-join-7b09fcb3b745
Weitere Beispiele zu Lateral (andere Dialekte), funktioniert auch in DB2 for i:
https://blog.jooq.org/lateral-is-your-friend-to-create-local-column-variables-in-sql/
Beispiel aus dem Link:
<code class="sql keyword">SELECT</code> <code class="sql plain">actor_id, </code><code class="sql keyword">name</code><code class="sql plain">, name_length, </code><code class="sql color2">COUNT</code><code class="sql plain">(*)</code>
<code class="sql keyword">FROM</code>
<code class="sql spaces"> </code><code class="sql plain">actor </code><code class="sql color1">JOIN</code> <code class="sql plain">film_actor </code><code class="sql keyword">AS</code> <code class="sql plain">fa USING (actor_id),</code>
<code class="sql spaces"> </code><code class="sql plain">LATERAL (</code><code class="sql keyword">SELECT</code> <code class="sql plain">first_name || </code><code class="sql string">' '</code> <code class="sql plain">|| last_name </code><code class="sql keyword">AS</code> <code class="sql keyword">name</code><code class="sql plain">) </code><code class="sql keyword">AS</code> <code class="sql plain">t1,</code>
<code class="sql spaces"> </code><code class="sql plain">LATERAL (</code><code class="sql keyword">SELECT</code> <code class="sql plain">length(</code><code class="sql keyword">name</code><code class="sql plain">) </code><code class="sql keyword">AS</code> <code class="sql plain">name_length) </code><code class="sql keyword">AS</code> <code class="sql plain">t2</code>
<code class="sql keyword">GROUP</code> <code class="sql keyword">BY</code> <code class="sql plain">actor_id, </code><code class="sql keyword">name</code><code class="sql plain">, name_length</code>
<code class="sql keyword">ORDER</code> <code class="sql keyword">BY</code> <code class="sql color2">COUNT</code><code class="sql plain">(*) </code><code class="sql keyword">DESC</code>
<code class="sql plain">LIMIT 5;</code>
In DB2 for i
<code class="sql keyword">SELECT</code> <code class="sql plain">actor_id, </code><code class="sql keyword">name</code><code class="sql plain">, name_length, </code><code class="sql color2">COUNT</code><code class="sql plain">(*)</code>
<code class="sql keyword">FROM</code>
<code class="sql spaces"> </code><code class="sql plain">actor </code><code class="sql color1">JOIN</code> <code class="sql plain">film_actor </code><code class="sql keyword">AS</code> <code class="sql plain">fa USING (actor_id),</code>
<code class="sql spaces"> </code><code class="sql plain">LATERAL (values(</code> <code class="sql plain">first_name || </code><code class="sql string">' '</code> <code class="sql plain">|| last_name)</code><code class="sql plain">) </code><code class="sql keyword">AS</code> <code class="sql plain">t1 (name),</code>
<code class="sql spaces"> </code><code class="sql plain">LATERAL (values</code>(<code class="sql plain"> length(</code><code class="sql keyword">name</code><code class="sql plain">))</code><code class="sql plain">) </code><code class="sql keyword">AS</code> <code class="sql plain">t2 (</code><code class="sql plain">name_length)</code>
<code class="sql keyword">GROUP</code> <code class="sql keyword">BY</code> <code class="sql plain">actor_id, </code><code class="sql keyword">name</code><code class="sql plain">, name_length</code>
<code class="sql keyword">ORDER</code> <code class="sql keyword">BY</code> <code class="sql color2">COUNT</code><code class="sql plain">(*) </code><code class="sql keyword">DESC</code>
<code class="sql plain">LIMIT 5;</code>
Interessant wirds dann bei Embedded SQL und Parametern:
select a.*
,a.Preis * Faktor
from Artikel a
cross join lateral(
values( :P1, :P2)
) p (Artikelnummer, Faktor)
where a.Artikelnummer = p.Artikelnummer
Vor allem, wenn man Parameter mehrfach in unterschiedlichen Teilen des SQL's benötigt, braucht man Parameter nur noch 1x per Lateral anhängen, da sie dann überall verwendet werden können. Somit ist die Wartung komplexer SQL's einfacher, wobei die Komplexität sogar noch sinkt.
Lateral wird im Gegensatz zum normalen Join für den Einzelzugriff optimiert und entspricht eher dem Programmiergedanken mit den Dateien.
Übrigens wurde Lateral mit SQL99 bereits eingeführt:
https://elephantdolphin.blogspot.com/2019/01/what-heck-is-lateral-derived-table.html
Und für die IBM kam es etwas später:
https://www.rpgpgm.com/2021/10/using-lateral-in-sql.html
Hier kann man auch schön sehen, dass ein Cross-Join durchaus Sinn macht.
Probierts einfach aus, es ist wirklich genial!
camouflage
25-07-25, 15:08
Der Griff nach KI ist meist ein Zeichen von Mangel an NI oder Faulheit - kann aber nach umgekehrtem Eiffelturm-Prinzip durchaus Karriere-fördernd sein.
Dieter, Dieter,
Hallo, wir sind nun mal in dieser KI Zeit angekommen, warum denn nicht auch diese nutzen? Ja, ich brauche ChatGPT ziemlich häufig, weil mir dieser die Statements ziemlich zuverlässig zusammenstellt, bei entsprechender Problemstellung.
Und es ist nicht ein Mangel an NI oder Faulheit, sondern ein Zeichen von Effizienz. Den Weg zur Lösung kenne ich ja, warum soll ich dann Zeit mit Tippen oder Suchen nach der korrekten Syntax verplempern.
Abgesehen davon ist die KI auch nicht immer glückselig machend, ohne Knowhow zur Kontrolle ist man hoffnungslos verloren.
Stimmt, solange ChatGPT den Lateral nicht kennt, fühle ich mich im Vorteil;-).
camouflage
25-07-25, 16:34
Stimmt, solange ChatGPT den Lateral nicht kennt, fühle ich mich im Vorteil;-).
Da wäre ich mir nicht so sicher.... ;-)
Dieter, Dieter,
Hallo, wir sind nun mal in dieser KI Zeit angekommen, warum denn nicht auch diese nutzen? Ja, ich brauche ChatGPT ziemlich häufig, weil mir dieser die Statements ziemlich zuverlässig zusammenstellt, bei entsprechender Problemstellung.
Und es ist nicht ein Mangel an NI oder Faulheit, sondern ein Zeichen von Effizienz. Den Weg zur Lösung kenne ich ja, warum soll ich dann Zeit mit Tippen oder Suchen nach der korrekten Syntax verplempern.
Abgesehen davon ist die KI auch nicht immer glückselig machend, ohne Knowhow zur Kontrolle ist man hoffnungslos verloren.
... man muss nicht jedem Marketing Blödsinn hinterherlaufen. Aber jeder, wie er kann.
Andreas_Prouza
28-07-25, 08:13
Ich bin auch davon überzeugt, dass das Internet nur eine Modeerscheinung ist. In ein paar Jahren redet bestimmt keiner mehr darüber.
Es gibt Gerüchte, dass Hammer und Meißel langsam wieder in Trend kommen sollen.
Da hast du gar nicht so unrecht.
- In Paderborn, im Nixdorf-Museum (meinem früheren Arbeitsplatz), wurde ein neuer menschlicher Roboter aufgestellt, der alle Sprachen beherrscht und nun auch mit Mimik überzeugt.
- In den USA gibts ein Start-Up, dass menschliche Roboter erzeugen will, die uns alle Arbeiten abnehmen sollen, https://www.1x.tech/neo. Interessant hier ist, dass man selber noch einkaufen geht. Das kann doch schon der Kühlschrank selber.
- https://www.play3.de/2025/07/15/microsoft-gaming-entwickler-durch-eigene-ki-tools-ersetzt-king-studios-betroffen/
Hammer und Meißel brauchen wir dann auch nicht mehr selber in die Hand zu nehmen, man sitzt dann ganz entspannt auf dem Sofa und daddelt verblödend vor sich hin.
Spätestens, wenn ein Roboter dir dann sanft über den Kopf streicht und dabei sagt "Brav! Das hast du aber fein gemacht." und einen Lutscher reicht, sollten wir wohl doch aufmerksam werden.
Ich bin gespannt, was die Datenschützer dann noch auflegen wollen.
Leider bin ich noch nicht zu alt, das nicht mehr erleben zu müssen. Allerdings wäre das ja für die Pflege bei uns nur von Vorteil;-).