Ich bin nun mal auf einem Kundensystem und zeige euch einen SQL, der so einiges zusammenfasst:
- Bestandsanalyse über den gesamten Artikelstamm
- Summe Lagerbestände über alle Läger
- Ermitteln Anzahl Unterdeckungen Mindest-/-lagerbestand
- Ermitteln Verbrauchsdaten für 6/12/18/24-Monte (Pivotfunktion)
- Errechnen Inventurwert an Hand des letzten EK-Wertes
- Ausgabe in einer Datei für eine CSV-Ausgabe

Und das alles in einem SQL mittels Lateral, was ohne nicht performant gewesen wäre bzw. nur per Programm lösbar.
Felder, die mit "§" anfangen sind Userparameter, die per Programm dann ersetzt werden.
Der gravierende Vorteil hier ist, dass der Join auf Satz- und nicht Group By-Ebene erfolgt und der Optimizer direkt die Daten mit der Where-Klausel liest.
Wichtig zu wissen ist, dass der Lateral Join eine Single-Access-Optimierung erfährt, da mit jeder Zeile auf den Join direkt zugegriffen wird.

Code:
-- Ausgabetabelle erstellen

create TABLE qtemp/bestausw as (
 select a.ARTIKELKENNZEICHEN
       ,a.ARTIKELNUMMER
       ,a.ARTIKELBEZEICHNUNG1
       ,a.ARTIKELBEZEICHNUNG2
       ,a.ARTIKELBEZEICHNUNG3
       ,a.ARTIKELBEZEICHNUNG4
       ,a.VERKAUFSFAEHIG
       ,a.VERKAUFSFAEHIGTEXT
       ,a.PRODUKTSCHLUESSEL
       ,a.PRODUKTSLTEXT
       ,a.ARTIKELGRUPPE
       ,a.ARTIKELGRUPPETEXT
       ,a.ARTIKELHAUPTGRUPPE
       ,a.ARTIKELHAUPTGRUPPETEXT
       ,a.ANLAGEDATUM


       ,l.*

        -- Berechnung aus letztem Einkauf (Tabelle D360)


       ,dec(round(w.lewerti / nullif(w.learbestd, 0) * l.LAGERBESTAND, 2), 15 , 2) Inventurwert
       ,dec(round(w.lewertv / nullif(w.learbestd, 0) * l.LAGERBESTAND, 2), 15 , 2) Vollkostwert


       ,l.Auftragsbestandgesamt - l.AuftragsbestandGebucht  AuftragsbestandNichtGebucht


       ,s.*


       ,v.*


       ,round(v.Verbrauch6M / 6.0, 2)        DVerbrauch6M
       ,round(v.Verbrauch12M / 12.0, 2)      DVerbrauch12M
       ,round(v.Verbrauch18M / 18.0, 2)      DVerbrauch18M
       ,round(v.Verbrauch24M / 24.0, 2)      DVerbrauch24M


       ,round((v.Verbrauch6M / double(6)) * 100.00
                / nullif(v.Verbrauch12M / double(12), 0) - 100.00, 2) Prozent6M
       ,round((v.Verbrauch12M / double(12)) * 100.00
                / nullif(v.Verbrauch18M / double(18), 0) - 100.00, 2) Prozent12M
       ,round((v.Verbrauch18M / double(18)) * 100.00
                / nullif(v.Verbrauch24M / double(24), 0) - 100.00, 2) Prozent18M
       ,round((v.Verbrauch24M / double(24)) * 100.00
                / nullif(v.DVerbrauchGesamt, 0) - 100.00, 2)          Prozent24M
       , current_timestamp                                         as Laufdatum


   from ARTSTAM01V a

   -- Ermitteln Summe aller Bestände und Reservierungen
   left join lateral (
       select
            sum(B.ARLAGB)           Lagerbestand
           ,sum(B.ARBB)             Bestellbestand
           ,sum(B.ARMINB)           Mindestbestand
           ,sum(B.ARMELD)           Meldebestand
           ,sum(B.ARAB + b.ARREVB)  Auftragsbestandgesamt
           ,sum(B.ARREVB)           Reservierterbestand
           ,sum(b.DPA01 + b.DPA02 + b.DPA03 + b.DPA04 + b.DPA05
              + b.DPA06 + b.DPA07 + b.DPA08 + b.DPA09 + b.DPA10
              + b.DPA11 + b.DPA12 + b.DPA13 + b.DPA14 + b.DPA15
              + b.DPA16 + b.DPA17 + b.DPA18 + b.DPA19 + b.DPA20
              + b.DPA21 + b.DPA22 + b.DPA23 + b.DPA24 + b.DPA25
              + b.DPA26 + b.DPA27 + b.DPA28 + b.DPA29 + b.DPA30
              + b.DPA31 + b.DPA32 + b.DPA33 + b.DPA34 + b.DPA35
              + b.DPA36 + b.DPA37 + b.DPA38 + b.DPA39 + b.DPA40
              + b.DPA41 + b.DPA42 + b.DPA43 + b.DPA44 + b.DPA45
              + b.DPA46 + b.DPA47 + b.DPA48 + b.DPA49 + b.DPA50
              + b.DPA51 + b.DPA52 + b.DPA53
              + b.DPRAB
              )                     AuftragsbestandGebucht
         from d031 B
        inner join LAGER ls
           on ls.KONZERNGESELLSCHAFT = a.KONZERNGESELLSCHAFT
        where a.KONZERNGESELLSCHAFT   = B.ARORT
          and a.ARTIKELKENNZEICHEN    = B.ARKZ
          and a.ARTIKELNUMMER         = B.ARNR
          and ls.LAGERORT             =
              case §LAGER when '' then '1' else §LAGER end
          and B.ARHALB in (ls.lagerort, ls.QSLAGER, ls.RAMPENLAGER)


        group by B.ARORT, b.ARKZ, b.ARNR
    ) l on 1=1

   -- Ermitteln Unterdeckungen


   left join lateral (
        select
              count(*)                        AnzahlTage
             ,sum(UNTERDECKUNGMINDESTBESTAND) UNTERDECKUNGMINDESTBESTAND
             ,sum(UNTERDECKUNGLAGERBESTAND)   UNTERDECKUNGLAGERBESTAND
         from D360VK01P d3
        where d3.KONZERNGESELLSCHAFT = a.KONZERNGESELLSCHAFT
          and d3.ARTIKELKENNZEICHEN  = a.ARTIKELKENNZEICHEN
          and d3.ARTIKELNUMMER       = a.ARTIKELNUMMER
          and d3.STATISTIKJAHR       = year(current date)
          and d3.LAGERNUMMER         =
              case §LAGER when '' then '1' else §LAGER end


        group by KONZERNGESELLSCHAFT
                ,ARTIKELKENNZEICHEN
                ,ARTIKELNUMMER
                ,STATISTIKJAHR
                ,LAGERNUMMER
    ) S on 1=1

   -- Ermitteln Monatsverbräuche als Pivot


   left join lateral (
        select
          sum(case when v.ARJJMM between year(current date - 6 months) * 100 + month(current date - 6 months)
                                     and year(current date - 1 months) * 100 + month(current date - 1 month)
                   then arvb end)    Verbrauch6M
          ,sum(case when v.ARJJMM between year(current date - 12 months) * 100 + month(current date - 12 months)
                                     and year(current date - 1 months) * 100 + month(current date - 1 month)
                   then arvb end)    Verbrauch12M
          ,sum(case when v.ARJJMM between year(current date - 18 months) * 100 + month(current date - 18 months)
                                     and year(current date - 1 months) * 100 + month(current date - 1 month)
                   then arvb end)    Verbrauch18M
          ,sum(case when v.ARJJMM between year(current date - 24 months) * 100 + month(current date - 24 months)
                                     and year(current date - 1 months) * 100 + month(current date - 1 month)
                   then arvb end)    Verbrauch24M


          ,sum(arvb)                 VerbrauchGesamt
          ,count(*) - 1              Monate
          ,round( sum(arvb) / double(nullif( count(*)-1, 0)), 2) DVerbrauchGesamt


          from d220 v
         where v.ARORT = a.KONZERNGESELLSCHAFT
           and v.ARKZ  = a.ARTIKELKENNZEICHEN
           and v.ARNR  = a.ARTIKELNUMMER
           group by v.ARORT, v.ARKZ, v.ARNR
    ) V on 1=1

  -- ermitteln letzten Einkauf je Artikel


  left join lateral (
       select *
         from d360 w
         where w.lenlg = a.KONZERNGESELLSCHAFT
           and w.LELAGNR =
              case §LAGER when '' then '1' else §LAGER end
           and w.LEARKZ = a.ARTIKELKENNZEICHEN
           and w.LEARNR = a.ARTIKELNUMMER
           order by ledatum desc
           limit 1
  ) w on 1=1


  where a.KONZERNGESELLSCHAFT = §KONZERN
    and status <> 'L'
 ) with data;