-
Mit Common Table Expressions hättest Du Dir eine ganze Menge COALESCES und Konvertierungen sparen können, ... und da nicht immer wieder alles mögliche wiederholt werden muss, wäre das Ganze auch weniger fehleranfällig.
Was die Casterei angeht. Wenn der Nenner eines Bruchs eine Dezimal-Zahl ist, wird intern automatisch in Float umgewandelt. Die übrigen Casts kannst Du Dir sparen. Was Du wissen musst, ist wenn du 2 Integer-Werte durcheinander dividierst wird das Ergebnis wieder ein Integer-Wert sein, d.h. Nachkommastellen werden abgeschnitten.
Spalten-Namen, die in der SELECT-Zeile definiert wurden, können im Order By angegeben werden, d.h. es ist nicht notwendig den ganzen Ausdruck nochmals zu kopieren.
Ich hab's mal versucht ein bisschen umzuschreiben. Da ich nicht weiß wie Deine Felder definiert sind, habe ich ausum2 explizit gecastet. (Ich kann's leider nicht testen, d.h. es könnte noch der eine oder andere Fehler drin sein.
Code:
With ulj as (select s3idn, sum(s3tlmg) as stlj
from stdprod.afs3sp
where substr(s3afa, 1, 1) not in ('M', 'Y', 'Z')
and s3rgd <= '20201031'
group by s3idn),
uvj as (select s3idn, sum(s3tlmg) as stvj
from wwdta.afs3spvj
where substr(s3afa, 1, 1) not in ('M', 'Y', 'Z')
group by s3idn),
uvvj as (select s3idn, sum(s3tlmg) as stvvj
from wwdta.afs3spvvj
where substr(s3afa, 1, 1) not in ('M', 'Y', 'Z')
group by s3idn),
bst as (select abidn, sum(abbst) as frei
from stdprod.afabsp
where substr(ablag, 3, 2) < '50'
group by abidn),
xJoin as (select asidn, asbz1, asbz2,
coalesce(stlj, 0.00) as stlj,
coalesce(stvj, 0.00) as stvj,
coalesce(stvvj, 0.00) as stvvj,
coalesce(frei, 0.00) as stfrei,
asabc, asme2,
Substr(asidn, 11, 1) as asidn111,
Substr(asidn, 13, 2) as asidn132,
Cast(asumf2 as Dec(31, 15) as asumf2,
Coalesce(".$totmon.", 00) as "$.totmon."
Coalesce(Stlj, 0) + Coalesce(Stvj, 0) + coalesce(Stvvj, 0) as St3J
from stdprod.afassp left join ulj on ulj.s3idn = asidn
left join uvj on uvj.s3idn = asidn
left join uvvj on uvvj.s3idn = asidn
left join bst on abidn = asidn)
select asidn, asbz1, asbz2,stlj, stvj, stvvj, stfrei,
Case When asumf2 <> 0 Then Stlj / asumf2 Else 0 End as qmlj,
Case When asumf2 <> 0 Then Stvj / asumf2 Else 0 End as qmvj,
case When asumf2 <> 0 Then Stvvj / asumf2 Else 0 End as qmvvj,
Case When asumf2 <> 0 Then StFrei / asumf2 Else 0 End as qmfrei,
st3J / 34,00 as stpromon,
st3J / 34,00 / asumf2 as qmpromon,
case when stlj <> 0 Then StFrei / Cast(Stlj as Dec(31, 15)) / 10,0
Else 0 End as rwlj,
case when St3j <> 0 Then StFrei / Cast(St3j as Dec(31, 15)) / ".$totmon"
Else 0 End as rw,
St3J / 34,00 * 9,00 - StFrei as stprod9
Case When asumf2 <> 0
Then (Cast(St3J as Dec(31, 15)) / 34,00 * 9 - StFrei) / asumf2
Else 0 End as qmprod9,
asabc,
asme2
from xJoin
where asidn111 = '1'
and asidn132 < '40'
and ( stlj > 0 or stvj > 0 or stvvj > 0 or Stfrei > 0)
order by case when asme2 = 'st' then Stprod9 Else qmprod9 end desc
-
"Wenn der Nenner eines Bruchs eine Dezimal-Zahl ist, wird intern automatisch in Float umgewandelt."
Wo steht das?
Es gibt da explizit Dezimalregeln, deshalb kann man auch per Option den Bereich von 31 auf 63 Stellen erweitern.
Double hat eine maximale Genauigkeit von 17 Stellen, somit würden Dezimal-Ergebnisse verfälscht.
Wenn bei einer komplexeren Formel Genauigkeit verloren geht, gibts nämlich einen Joblog-Eintrag sowie eine Warnung an das Programm mit einem entsprechenden SQLSTATE.
Ein expliziter Cast eines Divisors in höhere Genauigkeit verschärft das Problem zusaätzlich.
https://www.ibm.com/support/knowledgecenter/ssw_ibm_i_73/db2/rbafzdecarithmetic.htm
Was wohl korrekt ist:
Ist ein Operand Double/Float wird der gesamte Ausdruck als Double berechnet.
Zusätzlich hat ein Cast nichts mit der NULL-Problematik zu tun.
Die Frage ist lediglich, ob ASUMF2 bereits NULL enthalten kann und ggf. in COALESCE zu packen wäre.
Was den Konstantenwert im Coalesce angeht, so wird das Ergebnis nach den Rechenregeln automatisch angepasst:
coalesce(dec(1, 11, 2), 0) => dec(11, 2)
coalesce(dec(1, 11, 2), 0.000) => dec(12, 3)
usw.
Es reicht daher im Allgemeinen die Konstante 0 zu verwenden.
Natürlich gibt es noch die Integer-Regel:
Sind alle Operatoren ohne Dezimale, wird eine Integer-Operation durchgeführt.
Allerdings muss die Ganzzahl auch in einen passenden Integer-Typ castbar sein.
Similar Threads
-
By Peet in forum IBM i Hauptforum
Antworten: 1
Letzter Beitrag: 16-04-20, 14:18
-
By camouflage in forum IBM i Hauptforum
Antworten: 14
Letzter Beitrag: 18-02-20, 17:37
-
By alex61 in forum IBM i Hauptforum
Antworten: 21
Letzter Beitrag: 09-09-19, 18:55
-
By KingofKning in forum IBM i Hauptforum
Antworten: 8
Letzter Beitrag: 18-05-16, 14:11
-
By Burgy Zapp in forum IBM i Hauptforum
Antworten: 5
Letzter Beitrag: 11-12-13, 02:27
Berechtigungen
- Neue Themen erstellen: Nein
- Themen beantworten: Nein
- You may not post attachments
- You may not edit your posts
-
Foren-Regeln
|
Erweiterte Foren Suche
Google Foren Suche
Forum & Artikel Update eMail
AS/400 / IBM i
Server Expert Gruppen
Unternehmens IT
|
Kategorien online Artikel
- Big Data, Analytics, BI, MIS
- Cloud, Social Media, Devices
- DMS, Archivierung, Druck
- ERP + Add-ons, Business Software
- Hochverfügbarkeit
- Human Resources, Personal
- IBM Announcements
- IT-Karikaturen
- Leitartikel
- Load`n`go
- Messen, Veranstaltungen
- NEWSolutions Dossiers
- Programmierung
- Security
- Software Development + Change Mgmt.
- Solutions & Provider
- Speicher – Storage
- Strategische Berichte
- Systemmanagement
- Tools, Hot-Tips
Auf dem Laufenden bleiben
|
Bookmarks