Anmelden

View Full Version : SQL join mit nur letztem Satz



Seiten : [1] 2

Peet
21-07-25, 13:35
Hallo zusammen,
ich habe mal wieder eine Frage zu SQL...:

Ich möchte 2 PF's, Kundestamm und Auftragsdatei, in einem Join verknüpfen.
Kundenstamm ist die führende Datei, Verhältnis zur Auftragsdatei natürlich 1:n.

select a.*, b.*
from kunde a
left outer join (oder nur join, ist egal) auftrag b
on b.aufkdnr = a.kdskdnr

Dabei möchte ich aber nur die Verknüpfung mit dem neuesten Satz aus der Auftragsdatei,
kann ich über Zeitstempel erkennen.

Kann mir jemand auf die Sprünge helfen ???
Vielen Dank im Voraus.
Vg.
Peet

dschroeder
21-07-25, 14:06
Ich würde eine Common Table Expression verwenden, die mir zuerst die Aufträge mit dem jeweils neuesten Zeitstempel liefert. Dann würde ich darauf joinen:

Ungefähr so:




with neuesteAuftraege as (
select aufkdnr, max(zeitstempel) as newestTS
group by aufkdnr)

select * from kunde
join neuesteAuftraege on aufkdnr = kdnr and zeitsempel = newestTS

Fuerchau
21-07-25, 14:14
Lateral scheint immer noch unbekannt zu sein:




select a.*, b.*
from kunde a
left join lateral (
select * from auftrag b
where b.aufkdnr = a.kdskdnr
order by zeitstempel desc
limit 1
) b on 1 = 1


Empfehlenswert ist ein Index über Kunde und Zeitstempel.

Peet
21-07-25, 18:44
Vielen Dank an euch beide !

lateral war mir tatsächlich nicht bekannt, die Lösung von dschroeder in der Form auch noch nicht.
Vg.
Peet

KingofKning
22-07-25, 06:39
Hier mal die Antwort von der kostenfreien Chatgpt.

<main class="transition-width relative h-full w-full flex-1 overflow-auto" id="main" style="border: 0px solid rgba(13, 13, 13, 0.05); box-sizing: border-box; margin: 0px; padding: 0px; position: relative; height: 738.4px; width: 1268px; flex: 1 1 0%; overflow: auto; transition-duration: 0.15s; transition-property: width; transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); scrollbar-color: rgb(227, 227, 227) rgba(0, 0, 0, 0);"><article class="text-token-text-primary w-full" dir="auto" data-testid="conversation-turn-1" data-scroll-anchor="false" style="border: 0px solid rgba(13, 13, 13, 0.05); box-sizing: border-box; margin: 0px; padding: 0px; width: 1237.6px; color: rgb(13, 13, 13);">Du:

Ich möchte 2 PF's, Kundestamm und Auftragsdatei, in einem Join verknüpfen. Kundenstamm ist die führende Datei, Verhältnis zur Auftragsdatei natürlich 1:n. select a.*, b.* from kunde a left outer join (oder nur join, ist egal) auftrag b on b.aufkdnr = a.kdskdnr Dabei möchte ich aber nur die Verknüpfung mit dem neuesten Satz aus der Auftragsdatei, kann ich über Zeitstempel erkennen.



</article><article class="text-token-text-primary w-full" dir="auto" data-testid="conversation-turn-2" data-scroll-anchor="false" style="border: 0px solid rgba(13, 13, 13, 0.05); box-sizing: border-box; margin: 0px; padding: 0px; width: 1237.6px; color: rgb(13, 13, 13);">ChatGPT:

Um in einem SQL-Join nur den neuesten Satz aus der Auftragsdatei (1:n-Verhältnis) pro Kunde zu bekommen, kannst du ein Unter-Select oder ein CTE (Common Table Expression) verwenden, um pro Kunde den Auftrag mit dem neuesten Zeitstempel zu ermitteln.
Hier ist eine Lösung, die in vielen SQL-Dialekten (inkl. IBM DB2/AS/400 SQL) funktioniert:
? Variante mit <code data-start="379" data-end="390" style="border: 0px solid rgba(13, 13, 13, 0.05); box-sizing: border-box; margin: 0px; padding: 0.15rem 0.3rem; font-feature-settings: normal; font-family: ui-monospace, SFMono-Regular, &quot;SF Mono&quot;, Menlo, Consolas, &quot;Liberation Mono&quot;, monospace !important; font-size: 0.9em; font-variation-settings: normal; background-color: rgb(236, 236, 236); border-radius: 0.25rem; color: inherit; font-weight: 500;">LEFT JOIN</code> und <code data-start="395" data-end="420" style="border: 0px solid rgba(13, 13, 13, 0.05); box-sizing: border-box; margin: 0px; padding: 0.15rem 0.3rem; font-feature-settings: normal; font-family: ui-monospace, SFMono-Regular, &quot;SF Mono&quot;, Menlo, Consolas, &quot;Liberation Mono&quot;, monospace !important; font-size: 0.9em; font-variation-settings: normal; background-color: rgb(236, 236, 236); border-radius: 0.25rem; color: inherit; font-weight: 500;">SELECT MAX(zeitstempel)</code>:




<code class="whitespace-pre! language-sql" style="border: 0px solid rgba(13, 13, 13, 0.05); box-sizing: border-box; margin: 0px; padding: 0.1em; font-feature-settings: normal; font-family: ui-monospace, SFMono-Regular, &quot;SF Mono&quot;, Menlo, Consolas, &quot;Liberation Mono&quot;, monospace !important; font-size: inherit; font-variation-settings: normal; background: none; border-radius: 0.3em; color: rgb(56, 58, 66); font-weight: inherit; line-height: 1.5; white-space: normal; scrollbar-color: auto; overflow-wrap: normal; hyphens: none; tab-size: 4; word-break: normal; word-spacing: normal; text-align: left;">SELECT a.*, b.*
FROM kunde a
LEFT JOIN (
SELECT x.*
FROM auftrag x
INNER JOIN (
SELECT aufkdnr, MAX(zeitstempel) AS maxzeit
FROM auftrag
GROUP BY aufkdnr
) y ON x.aufkdnr = y.aufkdnr AND x.zeitstempel = y.maxzeit
) b ON a.kdskdnr = b.aufkdnr
</code>

???? Erklärung:



<code data-start="741" data-end="744" style="border: 0px solid rgba(13, 13, 13, 0.05); box-sizing: border-box; margin: 0px; padding: 0.15rem 0.3rem; font-feature-settings: normal; font-family: ui-monospace, SFMono-Regular, &quot;SF Mono&quot;, Menlo, Consolas, &quot;Liberation Mono&quot;, monospace !important; font-size: 0.875em; font-variation-settings: normal; background-color: rgb(236, 236, 236); border-radius: 0.25rem; color: rgb(13, 13, 13); font-weight: 500;">x</code> ist die komplette Auftragsdatei.
In der Unterabfrage <code data-start="800" data-end="803" style="border: 0px solid rgba(13, 13, 13, 0.05); box-sizing: border-box; margin: 0px; padding: 0.15rem 0.3rem; font-feature-settings: normal; font-family: ui-monospace, SFMono-Regular, &quot;SF Mono&quot;, Menlo, Consolas, &quot;Liberation Mono&quot;, monospace !important; font-size: 0.875em; font-variation-settings: normal; background-color: rgb(236, 236, 236); border-radius: 0.25rem; color: rgb(13, 13, 13); font-weight: 500;">y</code> ermittelst du je Kunde (<code data-start="828" data-end="837" style="border: 0px solid rgba(13, 13, 13, 0.05); box-sizing: border-box; margin: 0px; padding: 0.15rem 0.3rem; font-feature-settings: normal; font-family: ui-monospace, SFMono-Regular, &quot;SF Mono&quot;, Menlo, Consolas, &quot;Liberation Mono&quot;, monospace !important; font-size: 0.875em; font-variation-settings: normal; background-color: rgb(236, 236, 236); border-radius: 0.25rem; color: rgb(13, 13, 13); font-weight: 500;">aufkdnr</code>) den maximalen Zeitstempel.
Dann verbindest du <code data-start="891" data-end="894" style="border: 0px solid rgba(13, 13, 13, 0.05); box-sizing: border-box; margin: 0px; padding: 0.15rem 0.3rem; font-feature-settings: normal; font-family: ui-monospace, SFMono-Regular, &quot;SF Mono&quot;, Menlo, Consolas, &quot;Liberation Mono&quot;, monospace !important; font-size: 0.875em; font-variation-settings: normal; background-color: rgb(236, 236, 236); border-radius: 0.25rem; color: rgb(13, 13, 13); font-weight: 500;">x</code> mit <code data-start="899" data-end="902" style="border: 0px solid rgba(13, 13, 13, 0.05); box-sizing: border-box; margin: 0px; padding: 0.15rem 0.3rem; font-feature-settings: normal; font-family: ui-monospace, SFMono-Regular, &quot;SF Mono&quot;, Menlo, Consolas, &quot;Liberation Mono&quot;, monospace !important; font-size: 0.875em; font-variation-settings: normal; background-color: rgb(236, 236, 236); border-radius: 0.25rem; color: rgb(13, 13, 13); font-weight: 500;">y</code>, um nur den Auftrag mit dem neuesten Zeitstempel pro Kunde zu bekommen.
Danach machst du einen Join mit der Kundenstammtabelle <code data-start="1036" data-end="1039" style="border: 0px solid rgba(13, 13, 13, 0.05); box-sizing: border-box; margin: 0px; padding: 0.15rem 0.3rem; font-feature-settings: normal; font-family: ui-monospace, SFMono-Regular, &quot;SF Mono&quot;, Menlo, Consolas, &quot;Liberation Mono&quot;, monospace !important; font-size: 0.875em; font-variation-settings: normal; background-color: rgb(236, 236, 236); border-radius: 0.25rem; color: rgb(13, 13, 13); font-weight: 500;">a</code>.

? Hinweise:



Achte auf Datentyp-Kompatibilität bei <code data-start="1103" data-end="1116" style="border: 0px solid rgba(13, 13, 13, 0.05); box-sizing: border-box; margin: 0px; padding: 0.15rem 0.3rem; font-feature-settings: normal; font-family: ui-monospace, SFMono-Regular, &quot;SF Mono&quot;, Menlo, Consolas, &quot;Liberation Mono&quot;, monospace !important; font-size: 0.875em; font-variation-settings: normal; background-color: rgb(236, 236, 236); border-radius: 0.25rem; color: rgb(13, 13, 13); font-weight: 500;">zeitstempel</code> (z.?B. <code data-start="1124" data-end="1130" style="border: 0px solid rgba(13, 13, 13, 0.05); box-sizing: border-box; margin: 0px; padding: 0.15rem 0.3rem; font-feature-settings: normal; font-family: ui-monospace, SFMono-Regular, &quot;SF Mono&quot;, Menlo, Consolas, &quot;Liberation Mono&quot;, monospace !important; font-size: 0.875em; font-variation-settings: normal; background-color: rgb(236, 236, 236); border-radius: 0.25rem; color: rgb(13, 13, 13); font-weight: 500;">DATE</code>, <code data-start="1132" data-end="1143" style="border: 0px solid rgba(13, 13, 13, 0.05); box-sizing: border-box; margin: 0px; padding: 0.15rem 0.3rem; font-feature-settings: normal; font-family: ui-monospace, SFMono-Regular, &quot;SF Mono&quot;, Menlo, Consolas, &quot;Liberation Mono&quot;, monospace !important; font-size: 0.875em; font-variation-settings: normal; background-color: rgb(236, 236, 236); border-radius: 0.25rem; color: rgb(13, 13, 13); font-weight: 500;">TIMESTAMP</code>, <code data-start="1145" data-end="1151" style="border: 0px solid rgba(13, 13, 13, 0.05); box-sizing: border-box; margin: 0px; padding: 0.15rem 0.3rem; font-feature-settings: normal; font-family: ui-monospace, SFMono-Regular, &quot;SF Mono&quot;, Menlo, Consolas, &quot;Liberation Mono&quot;, monospace !important; font-size: 0.875em; font-variation-settings: normal; background-color: rgb(236, 236, 236); border-radius: 0.25rem; color: rgb(13, 13, 13); font-weight: 500;">CHAR</code>).
Falls mehrere Aufträge den exakt gleichen Zeitstempel haben, werden alle zurückgegeben.
Du kannst <code data-start="1260" data-end="1271" style="border: 0px solid rgba(13, 13, 13, 0.05); box-sizing: border-box; margin: 0px; padding: 0.15rem 0.3rem; font-feature-settings: normal; font-family: ui-monospace, SFMono-Regular, &quot;SF Mono&quot;, Menlo, Consolas, &quot;Liberation Mono&quot;, monospace !important; font-size: 0.875em; font-variation-settings: normal; background-color: rgb(236, 236, 236); border-radius: 0.25rem; color: rgb(13, 13, 13); font-weight: 500;">LEFT JOIN</code> verwenden, damit auch Kunden ohne Auftrag angezeigt werden.

Wenn du auf einer AS/400 (iSeries, Db2 for i) arbeitest und lieber mit <code data-start="1413" data-end="1421" style="border: 0px solid rgba(13, 13, 13, 0.05); box-sizing: border-box; margin: 0px; padding: 0.15rem 0.3rem; font-feature-settings: normal; font-family: ui-monospace, SFMono-Regular, &quot;SF Mono&quot;, Menlo, Consolas, &quot;Liberation Mono&quot;, monospace !important; font-size: 0.875em; font-variation-settings: normal; background-color: rgb(236, 236, 236); border-radius: 0.25rem; color: rgb(13, 13, 13); font-weight: 500;">RANK()</code> oder <code data-start="1427" data-end="1441" style="border: 0px solid rgba(13, 13, 13, 0.05); box-sizing: border-box; margin: 0px; padding: 0.15rem 0.3rem; font-feature-settings: normal; font-family: ui-monospace, SFMono-Regular, &quot;SF Mono&quot;, Menlo, Consolas, &quot;Liberation Mono&quot;, monospace !important; font-size: 0.875em; font-variation-settings: normal; background-color: rgb(236, 236, 236); border-radius: 0.25rem; color: rgb(13, 13, 13); font-weight: 500;">ROW_NUMBER()</code> arbeitest (ab V7R1+), kann ich dir auch diese Variante zeigen.
Möchtest du das lieber mit <code data-start="1533" data-end="1547" style="border: 0px solid rgba(13, 13, 13, 0.05); box-sizing: border-box; margin: 0px; padding: 0.15rem 0.3rem; font-feature-settings: normal; font-family: ui-monospace, SFMono-Regular, &quot;SF Mono&quot;, Menlo, Consolas, &quot;Liberation Mono&quot;, monospace !important; font-size: 0.875em; font-variation-settings: normal; background-color: rgb(236, 236, 236); border-radius: 0.25rem; color: rgb(13, 13, 13); font-weight: 500;">ROW_NUMBER()</code>?

Du:

Hast Du auch eine Lösung mit Lateral?


</article><article class="text-token-text-primary w-full" dir="auto" data-testid="conversation-turn-4" data-scroll-anchor="true" style="border: 0px solid rgba(13, 13, 13, 0.05); box-sizing: border-box; margin: 0px; padding: 0px; width: 1237.6px; color: rgb(13, 13, 13); min-height: calc(-248px + 100dvh);">ChatGPT:



<button class="flex w-full items-center gap-0.5" style="border: 0px solid rgba(13, 13, 13, 0.05); box-sizing: border-box; margin: 0px; padding: 0px; background-color: rgba(0, 0, 0, 0); border-radius: 0px; color: inherit; font: inherit; letter-spacing: inherit; opacity: 1; appearance: button; cursor: pointer; display: flex; width: 614.4px; align-items: center; gap: 2px;">Nachgedacht für 34 Sekunden<svg width="20" height="20" viewBox="0 0 20 20" fill="currentColor" xmlns="http://www.w3.org/2000/svg" data-rtl-flip="" class="icon-sm text-token-text-secondary inline align-middle transition-transform"></svg>
</button>



Lösung mit?<code data-start="15" data-end="24" style="border: 0px solid rgba(13, 13, 13, 0.05); box-sizing: border-box; margin: 0px; padding: 0.15rem 0.3rem; font-feature-settings: normal; font-family: ui-monospace, SFMono-Regular, &quot;SF Mono&quot;, Menlo, Consolas, &quot;Liberation Mono&quot;, monospace !important; font-size: 0.9em; font-variation-settings: normal; background-color: rgb(236, 236, 236); border-radius: 0.25rem; color: inherit; font-weight: 500;">LATERAL</code>?(“CROSS/LEFT?JOIN?LATERAL”)

Ab IBM?i?7.1 (bzw. Db2?for?i 7.1) steht Ihnen der LATERAL?Join zur Verfügung. Er erlaubt es, in einer abgeleiteten Tabelle (Subselect) auf Spalten der zuvor genannten Tabellen zuzugreifen?–?vergleichbar mit <code data-start="261" data-end="274" style="border: 0px solid rgba(13, 13, 13, 0.05); box-sizing: border-box; margin: 0px; padding: 0.15rem 0.3rem; font-feature-settings: normal; font-family: ui-monospace, SFMono-Regular, &quot;SF Mono&quot;, Menlo, Consolas, &quot;Liberation Mono&quot;, monospace !important; font-size: 0.875em; font-variation-settings: normal; background-color: rgb(236, 236, 236); border-radius: 0.25rem; color: rgb(13, 13, 13); font-weight: 500;">CROSS APPLY</code> in SQL?Server. Dadurch können Sie in einem einzigen Schritt pro Kunde genau den jüngsten Auftrag ziehen.



<code class="whitespace-pre! language-sql" style="border: 0px solid rgba(13, 13, 13, 0.05); box-sizing: border-box; margin: 0px; padding: 0.1em; font-feature-settings: normal; font-family: ui-monospace, SFMono-Regular, &quot;SF Mono&quot;, Menlo, Consolas, &quot;Liberation Mono&quot;, monospace !important; font-size: inherit; font-variation-settings: normal; background: none; border-radius: 0.3em; color: rgb(56, 58, 66); font-weight: inherit; line-height: 1.5; white-space: normal; scrollbar-color: auto; overflow-wrap: normal; hyphens: none; tab-size: 4; word-break: normal; word-spacing: normal; text-align: left;">SELECT a.*, -- alle Felder aus dem Kundenstamm
b.* -- plus Felder des jüngsten Auftrags
FROM kunde a
LEFT JOIN LATERAL -- oder CROSS JOIN LATERAL = INNER?Verknüpfung
( SELECT b.* -- Unterabfrage = “pro Kunde Aufträge”
FROM auftrag b
WHERE b.aufkdnr = a.kdskdnr -- korreliert über Kundennummer
ORDER BY b.zeitstempel DESC -- jüngster zuerst
FETCH FIRST 1 ROW ONLY -- genau EIN Datensatz
) b
ON 1 = 1 ; -- Dummy?ON (bei LEFT JOIN LATERAL erforderlich)
</code>


<tbody>
Variante
Wirkung


<code data-start="1088" data-end="1116" style="border: 0px solid rgba(13, 13, 13, 0.05); box-sizing: border-box; margin: 0px; padding: 0.15rem 0.3rem; font-feature-settings: normal; font-family: ui-monospace, SFMono-Regular, &quot;SF Mono&quot;, Menlo, Consolas, &quot;Liberation Mono&quot;, monospace !important; font-size: 0.875em; font-variation-settings: normal; background-color: rgb(236, 236, 236); border-radius: 0.25rem; color: rgb(13, 13, 13); font-weight: 500;">LEFT JOIN LATERAL … ON 1=1</code>

Alle Kunden bleiben erhalten; bei fehlenden Aufträgen sind die Spalten aus?<code data-start="1194" data-end="1197" style="border: 0px solid rgba(13, 13, 13, 0.05); box-sizing: border-box; margin: 0px; padding: 0.15rem 0.3rem; font-feature-settings: normal; font-family: ui-monospace, SFMono-Regular, &quot;SF Mono&quot;, Menlo, Consolas, &quot;Liberation Mono&quot;, monospace !important; font-size: 0.875em; font-variation-settings: normal; background-color: rgb(236, 236, 236); border-radius: 0.25rem; color: rgb(13, 13, 13); font-weight: 500;">b</code>?NULL.


<code data-start="1208" data-end="1230" style="border: 0px solid rgba(13, 13, 13, 0.05); box-sizing: border-box; margin: 0px; padding: 0.15rem 0.3rem; font-feature-settings: normal; font-family: ui-monospace, SFMono-Regular, &quot;SF Mono&quot;, Menlo, Consolas, &quot;Liberation Mono&quot;, monospace !important; font-size: 0.875em; font-variation-settings: normal; background-color: rgb(236, 236, 236); border-radius: 0.25rem; color: rgb(13, 13, 13); font-weight: 500;">CROSS JOIN LATERAL …</code>
Entspricht einem?INNER?Join: Nur Kunden mit mindestens einem Auftrag werden gezeigt.


<code data-start="1322" data-end="1351" style="border: 0px solid rgba(13, 13, 13, 0.05); box-sizing: border-box; margin: 0px; padding: 0.15rem 0.3rem; font-feature-settings: normal; font-family: ui-monospace, SFMono-Regular, &quot;SF Mono&quot;, Menlo, Consolas, &quot;Liberation Mono&quot;, monospace !important; font-size: 0.875em; font-variation-settings: normal; background-color: rgb(236, 236, 236); border-radius: 0.25rem; color: rgb(13, 13, 13); font-weight: 500;">FETCH FIRST 1 ROW WITH TIES</code>

Liefert alle Aufträge, falls mehrere den exakt gleichen Zeitstempel haben.

</tbody>


Warum das funktioniert



LATERAL sorgt dafür, dass die Unterabfrage für jede Zeile von?<code data-start="1531" data-end="1538" style="border: 0px solid rgba(13, 13, 13, 0.05); box-sizing: border-box; margin: 0px; padding: 0.15rem 0.3rem; font-feature-settings: normal; font-family: ui-monospace, SFMono-Regular, &quot;SF Mono&quot;, Menlo, Consolas, &quot;Liberation Mono&quot;, monospace !important; font-size: 0.875em; font-variation-settings: normal; background-color: rgb(236, 236, 236); border-radius: 0.25rem; color: rgb(13, 13, 13); font-weight: 500;">kunde</code> separat ausgeführt wird – also „row?by?row“.?
RPGPGM.COM - From AS400 to IBM i

(https://www.rpgpgm.com/2021/10/using-lateral-in-sql.html)
Durch das <code data-start="1638" data-end="1673" style="border: 0px solid rgba(13, 13, 13, 0.05); box-sizing: border-box; margin: 0px; padding: 0.15rem 0.3rem; font-feature-settings: normal; font-family: ui-monospace, SFMono-Regular, &quot;SF Mono&quot;, Menlo, Consolas, &quot;Liberation Mono&quot;, monospace !important; font-size: 0.875em; font-variation-settings: normal; background-color: rgb(236, 236, 236); border-radius: 0.25rem; color: rgb(13, 13, 13); font-weight: 500;">ORDER BY … FETCH FIRST 1 ROW ONLY</code> wird in der Unterabfrage genau der neueste Auftrag des jeweiligen Kunden ausgewählt, bevor die Daten wieder nach außen gereicht werden.?
BlogFaq400
(https://blog.faq400.com/en/db2-for-i/sql-lateral-join-db2-for-i-en/)
Stack Overflow
(https://stackoverflow.com/questions/19773998/how-to-left-join-in-db2-iseries-with-first-row)

Performance?Hinweise



Index auf?<code data-start="1897" data-end="1933" style="border: 0px solid rgba(13, 13, 13, 0.05); box-sizing: border-box; margin: 0px; padding: 0.15rem 0.3rem; font-feature-settings: normal; font-family: ui-monospace, SFMono-Regular, &quot;SF Mono&quot;, Menlo, Consolas, &quot;Liberation Mono&quot;, monospace !important; font-size: 0.875em; font-variation-settings: normal; background-color: rgb(236, 236, 236); border-radius: 0.25rem; color: rgb(13, 13, 13); font-weight: 500;">auftrag(aufkdnr, zeitstempel DESC)</code> beschleunigt die Unterabfrage enorm.
Bei sehr breiten Tabellen können Sie statt <code data-start="2019" data-end="2024" style="border: 0px solid rgba(13, 13, 13, 0.05); box-sizing: border-box; margin: 0px; padding: 0.15rem 0.3rem; font-feature-settings: normal; font-family: ui-monospace, SFMono-Regular, &quot;SF Mono&quot;, Menlo, Consolas, &quot;Liberation Mono&quot;, monospace !important; font-size: 0.875em; font-variation-settings: normal; background-color: rgb(236, 236, 236); border-radius: 0.25rem; color: rgb(13, 13, 13); font-weight: 500;">b.*</code> nur die benötigten Spalten auswählen.
Wenn Sie weitere Kriterien (Status, Jahr?usw.) haben, setzen Sie sie einfach zusätzlich in die Unterabfrage.

Damit haben Sie eine elegante, kompakte Alternative zu den klassischen Lösungen mit GROUP?BY?+?MAX oder OLAP?Funktionen – lesbarer und häufig sogar schneller.









</article>

<button class="cursor-pointer absolute z-10 rounded-full bg-clip-padding border text-token-text-secondary border-token-border-default end-1/2 translate-x-1/2 bg-token-main-surface-primary w-8 h-8 flex items-center justify-center bottom-[calc(var(--composer-overlap-px)+--spacing(6))]" style="border: 1px solid rgba(13, 13, 13, 0.1); box-sizing: border-box; margin: 0px; padding: 0px; background-color: rgb(255, 255, 255); border-radius: 3.40282e+38px; color: rgb(93, 93, 93); font: inherit; letter-spacing: inherit; opacity: 1; appearance: button; cursor: pointer; position: absolute; bottom: 79px; z-index: 10; display: flex; height: 32px; width: 32px; --tw-translate-x: 50%; translate: 50%; align-items: center; justify-content: center; background-clip: padding-box; inset-inline-end: 634px;"><svg style="width: 20px" height="20" viewBox="0 0 20 20" fill="currentColor" xmlns="http://www.w3.org/2000/svg" class="icon text-token-text-primary"></svg>
</button>




<button type="button" name="context-connector-pasted-link-popover-trigger" class="invisible absolute self-center" aria-hidden="true" tabindex="-1" aria-haspopup="dialog" aria-expanded="false" aria-controls="radix-«rm7»" data-state="closed" style="border: 0px solid rgba(13, 13, 13, 0.05); box-sizing: border-box; margin: 0px; padding: 0px; background-color: rgba(0, 0, 0, 0); border-radius: 0px; color: inherit; font: inherit; letter-spacing: inherit; opacity: 1; appearance: button; cursor: pointer; visibility: hidden; position: absolute; align-self: center;"></button>
<form class="w-full [view-transition-name:var(--vt-composer)]" data-type="unified-composer" style="border: 0px solid rgba(13, 13, 13, 0.05); box-sizing: border-box; margin: 0px; padding: 0px; width: 768px; view-transition-name: none;">










<button data-testid="composer-speech-button" aria-label="Audiomodus starten" class="relative flex h-9 items-center justify-center rounded-full transition-colors disabled:text-gray-50 disabled<img src=" images="" smilies="" redface.gif"="" border="0" alt="" title="Embarrassment" smilieid="3">pacity-30 w-9 bg-[#00000014] dark:bg-[#FFFFFF29] text-token-text-primary hover:bg-[#0000001F] hover:dark:bg-[#FFFFFF3D]" style="border: 0px solid rgba(13, 13, 13, 0.05); box-sizing: border-box; margin: 0px; padding: 0px; background-color: rgba(0, 0, 0, 0.08); border-radius: 3.40282e+38px; color: rgb(13, 13, 13); font: inherit; letter-spacing: inherit; opacity: 1; appearance: button; cursor: pointer; position: relative; display: flex; height: 36px; width: 36px; align-items: center; justify-content: center; transition-duration: 0.15s; transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to; transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); view-transition-name: none;"><svg width="20" height="20" viewBox="0 0 20 20" fill="currentColor" xmlns="http://www.w3.org/2000/svg" class="icon"></svg>

</button>






</form>
<input class="sr-only" tabindex="-1" aria-hidden="true" id="upload-photos" accept="image/*" multiple="" type="file" style="border-width: 0px; border-style: solid; border-color: inherit; border-image: initial; box-sizing: border-box; margin: -1px; padding: 0px; background: unset; border-radius: 0px; color: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; font-size: unset; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-size-adjust: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; letter-spacing: inherit; opacity: 1; --tw-shadow: 0 0 #0000; appearance: none; print-color-adjust: unset; clip: rect(0px, 0px, 0px, 0px); height: 1px; overflow: hidden; position: absolute; white-space: nowrap; width: 1px;"><input class="sr-only" tabindex="-1" aria-hidden="true" id="upload-camera" accept="image/*" multiple="" type="file" style="border-width: 0px; border-style: solid; border-color: inherit; border-image: initial; box-sizing: border-box; margin: -1px; padding: 0px; background: unset; border-radius: 0px; color: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; font-size: unset; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-size-adjust: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; letter-spacing: inherit; opacity: 1; --tw-shadow: 0 0 #0000; appearance: none; print-color-adjust: unset; clip: rect(0px, 0px, 0px, 0px); height: 1px; overflow: hidden; position: absolute; white-space: nowrap; width: 1px;">



ChatGPT kann Fehler machen. Überprüfe wichtige Informationen. Siehe Cookie-Voreinstellungen.




</main>

B.Hauser
22-07-25, 07:31
Mir ist nachwie vor nicht klar warum ihr unbedingt LATERAL verwenden wollt!
Die beste Lösung (i.Ü. auch die performanteste) ist die Lösung von Dieter, d.h. die Verwendung von Common Table Expressions.

Die Lösung mit LATERAL ist ungeführt 3x langsamger wie die Lösung mit CTE. Sagt zumindest Visual Explain, wenn man beide Syntaxen durchlaufen lässt. Ich habe leider in meinen Spiel-Dateien nicht genug Daten, so dass man den Unterschied tatsächlich merken könnte.

... das behauptet auch ChatGPT:
Du liegst mit deiner Strategie (CTEs > Subselects/OLAP > LATERAL/Skalare) vollkommen richtig – besonders in einem System, das du verstehen, testen und langfristig warten möchtest.

KingofKning
22-07-25, 07:47
Mir persönlich ging es eigentlich nur darum zu zeigen wie gut die Antworten auf die gestellten Fragen waren.
Ich bin von beiden Antworten positiv überrascht und hätte nicht vermutet das eine Software die in meinen Augen gute Lösung in sekundenschnelle liefert.

Wenn ich noch Programmierer wäre bekäme ich langsam Angst um meinen Job.

GG 2139

Peet
22-07-25, 09:26
Mir persönlich ging es eigentlich nur darum zu zeigen wie gut die Antworten auf die gestellten Fragen waren.
Ich bin von beiden Antworten positiv überrascht und hätte nicht vermutet das eine Software die in meinen Augen gute Lösung in sekundenschnelle liefert.

Wenn ich noch Programmierer wäre bekäme ich langsam Angst um meinen Job.

GG 2139

Vielen Dank.
Es freut micht dass du mit ChatGtp in so kurzer Zeit ein Ergebnis erzielt hast.
vg.
Peet

Peet
22-07-25, 09:26
Mir ist nachwie vor nicht klar warum ihr unbedingt LATERAL verwenden wollt!
Die beste Lösung (i.Ü. auch die performanteste) ist die Lösung von Dieter, d.h. die Verwendung von Common Table Expressions.

Die Lösung mit LATERAL ist ungeführt 3x langsamger wie die Lösung mit CTE. Sagt zumindest Visual Explain, wenn man beide Syntaxen durchlaufen lässt. Ich habe leider in meinen Spiel-Dateien nicht genug Daten, so dass man den Unterschied tatsächlich merken könnte.

... das behauptet auch ChatGPT:
Du liegst mit deiner Strategie (CTEs > Subselects/OLAP > LATERAL/Skalare) vollkommen richtig – besonders in einem System, das du verstehen, testen und langfristig warten möchtest.

Hallo Birgita,
vielen Dank für die Infos.
Vg.
Peet

Fuerchau
22-07-25, 09:36
@Birgittta
Meine Erfahrung spricht da vollkommen dagegen.
Lateral Table ist die bisher schnellste Möglichkeit, wie ich festgestellt habe, z.B. per where ... Order By ... Limit n, Sätze zu joinen oder eben auch einen "select Aggregates from .. where .." ohne aufwändigen Group by zu verknüpfen.
Der Lateral ist letztlich genauso schnell wie die "Aggr() Over()"-Funktionen, die man früher auch mit CTE's o.ä. lösen musste. Und dagegen hast du ja auch nichts.

Per CTE oder auch derived Table einen Grouped Join durchzuführen ist merklich langsamer.
Dasselbe gilt auch für skalare Subselects, die damit vollkommen obsolet werden, zumal man mit den Ergebnissen des Laterals auch gleich weiterrechnen kann.
Vielleicht probiert du ihn einfach auch mal aus. Vor allem auf Tabellen mit ein paar 100.000 oder mehr Zeilen. Auf Testumgebungen mit ein paar 1000 Zeilen macht das natürlich kaum einen Unterschied.

Also rede den Leuten nicht ein, dass Lateral Unsinn sei. Es ist einer der effektivsten Joins überhaupt und so komplizierte CTE's wie oben angegeben sind nicht mehr erforderlich. Ich verwende den für fast alle Belange, die früher ungleich komplizierter waren.