Fragensteller
Abfrage mit komplexer Sortierung

Frage
-
Hallo,
ich bin neu im Forum - Level: kein Profi, aber ambitionierter Autodidakt :)
Es geht um eine Tabelle mit Bohrprofilen, welche normalerweise von einer Applikation verwaltet wird. Sie enthält mehrere Spalten mit hierarchisch strukturieren Daten, welche korrekt zu sortieren sind, um die korrekte Schichtabfolge zu erhalten.
Die wesentlichen Sortier-Spalten sind:
Projekt-ID, Lokalitaet-ID, Interpraetations-ID, Layer-ID, Sublayer-ID, Schicht-TiefeDie Lokalitäts-ID einer Bohrung gehört zu genau einer Projekt-ID und kann mehrere Profil-Interpretationen (Interpretations-IDs) besitzen. Die Sortierreihenfolge ist also noch trivial: Projekt-ID, Lokalitaet-ID, Interpraetations-ID
Jedes Tupel aus (Projekt-ID, Lokalitaet-ID, Interpraetations-ID) besitzt eine Anzahl von Schichten mit ihren Teufen als nachfolgendes (vertikales) Sortierkriterium, wobei jede Schicht eine nicht sortierfähige Layer-ID besitzt.
Das eigentliche Sortierproblem tritt auf, weil jede Schicht mehrere Unterschichten enthalten kann, welche über die Sublayer-ID aufsteigend sortiert werden müssen und selbst hierarchisch an den nicht sortierbaren Layer-IDs hängen. Ich hoffe, das war halbwegs verständlich.
Beispiel einer Bohrung mit korrekter Sortierung der Schichten:
Proj Lok Int Layer SubLay Tiefe
p1 1 0 0 0 52
p1 1 0 3 0 31
p1 1 0 2 0 24
p1 1 0 2 1 NULL
p1 1 0 2 2 27
p1 1 0 2 3 NULL
p1 1 0 25 0 -21
p1 1 1 2 1 52
p1 1 1 1 0 44
p1 1 1 5 1 35
p1 1 1 17 0 25
p1 1 1 17 1 NULL
p1 1 1 17 3 NULL
Lässt sich das in Form einer komplexeren Abfrage abbilden oder muss man hier mit stored procedures oder ... arbeiten?
Vielen Dank für weiterführende Hinweise!
Alle Antworten
-
Hi,
für mich war es leider nicht verständlich, da mir die Ausgangstruktur und deren Daten fehlen.
Poste daher bitte die CREATE TABLE oder DECLARE ... TABLE Statements der Tabellen, INSERT INTO Statements für Beispieldaten und das gewünschte Ergebnis, exakt auf diesen Beispieldaten basierend.
Dann kann man das auch mal nachstellen und sicher auch helfen.
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET (2001-2018)
https://www.asp-solutions.de/ - IT Beratung, Softwareentwicklung, Remotesupport -
Hallo,
die Datenbank zu welcher die Schichtdatentabelle gehört, wird von einer größeren Anwendung verwaltet und arbeitet mit praktisch jeder SQL-Datenbank zusammen. Daher handelt es bei der Datenbank um ein 'dummes' Speicher-Backend ohne Primär-/Fremdschlüssel, Relationen oder Indexe.
Die Herstellerfirma gibt an, dass für jede Profil-Interpretation (Interpretations-ID) einer Bohrung die Schichttiefe das Haupt-Sortierkriterium ist. Mit jeder Profil-Interpretation wird auch eine eigene Layer-ID-Sequenz verwaltet, wobei der Wert mit jedem neuen Eintrag iteriert wird. D.h. wird in einer späteren Überarbeitung eine Schicht irgendwo im Bohrprofil neu hinzugefügt, wird der Wert mit <max(Layer-ID) + 1> iteriert und entfällt somit als Sortierkriterium.
Unterscheiden werden Hauptschichten (Layer-ID) und Unterschichten (SubLayer-ID):
Während für jede Hauptschicht eine Tiefe existiert, sind für Unterschichten keine Tiefenangaben erforderlich. Sie sind, wie in der Beispiel-Tabelle gezeigt an die Layer-ID gebunden, wobei die SubLayer-ID selbst tatsächlich aufsteigend sortiert wird. Unterschichten haben daher eher den Charakter einer nach Eingabe-Reihenfolge geordneten 'Liste von zusätzlichen Schichtmerkmalen'.
Das 'create table' statement kann ich nicht einsehen, es würde aber wie folgt, aussehen:
create table geodin_loc_s3schdat
(
prj_id varchar(6) not null, -- Projekt-ID
locid smallint not null, -- Lokation-ID
recid smallint not null, -- Record-ID über alle Schichteinträge in der Tabelle
intv smallint not null, -- Interpretations-ID
layerid smallint not null, -- Layer-ID
layercntr smallint not null, -- SubLayer-ID
depthto float, -- Tiefe der unteren Schichtgrenze
strat varchar(254), -- Stratigrafie der Schicht
petro varchar(254), -- Boden- bzw. Gesteinstyp
... + weitere Schichtattribute
)Das "not null" Constraint habe ich eigenmächtig hinzugefügt, wo die Anwendung tatsächlich kontrolliert, dass Eintrage getätigt werden. Die Anwendung garantiert auch, dass für jede Hauptschicht eine Tiefenangabe erfolgt.
Die recid ist jeweils eindeutig im Bereich einer Profil-Interpretation, wird mit jedem Neueintrag einer Haupt- oder einer Unterschicht iteriert. Sie spielt für Abfragen daher keine Rolle.
Alle Inserts werden durch die Anwendung selbst gemäß obiger Beschreibung jeweils für Haupt- und Unterschichten vorgenommen.
Ich hoffe, dass es nun klarer ist. Die Logik ist leider nicht sehr schön gelöst - wahrscheinlich bedingt durch die Historie. Bohrdaten und Bohrdatenbanken sind eine Wissenschaft für sich.
Danke noch mal,
Torsten
- Bearbeitet thorskilde Mittwoch, 21. April 2021 08:57
-
Ich hatte vergessen, wie ich das 'create table' Statement übers Management Studio anzeigen kann (siehe unten). Außerdem muss ich mich korrigieren. Alle Hauptschichten sind mit der SubLayer-ID = 0 codiert. Die korrekt sortierte Beispiel-Tabelle sieht daher so aus:
Proj Lok Int Layer SubLay Tiefe
p1 1 0 0 0 52 Hauptschicht
p1 1 0 3 0 31 Hauptschicht
p1 1 0 2 0 24 Hauptschicht
p1 1 0 2 1 NULL Unterschicht
p1 1 0 2 2 27 Unterschicht
p1 1 0 2 3 NULL Unterschicht
p1 1 0 25 0 -21 Hauptschicht
p1 1 1 2 0 52 Hauptschicht
p1 1 1 1 0 44 Hauptschicht
p1 1 1 5 0 35 Hauptschicht
p1 1 1 17 0 25 Hauptschicht
p1 1 1 17 1 NULL Unterschicht
p1 1 1 17 3 NULL Unterschicht
Dies ist die Tabellendefinition:
CREATE TABLE [dbo].[GEODIN_LOC_S3SCHDAT](
[PRJ_ID] [varchar](6) NULL,
[LOCID] [smallint] NULL,
[RECID] [smallint] NULL,
[INTV] [smallint] NULL,
[LAYERID] [smallint] NULL,
[LAYERCNTR] [smallint] NULL,
[DEPTHTO] [float] NULL,
[SART] [varchar](128) NULL,
[STRAT] [varchar](254) NULL,
[PETRO] [varchar](254) NULL,
... und so weiter
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]Bitte beachten, dass die Anwendung sicherstellt, dass die ersten 5 Spalten nicht Null werden können und die Schicht-Tiefe nur bei den Hauptschichten obligatorisch ist.
-
Die korrekt sortierte Beispiel-Tabelle sieht daher so aus:
Bitte noch die Originaldaten als INSERT INTO Statements posten. Man muss ja die Quelle und das Ziel sehen.
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET (2001-2018)
https://www.asp-solutions.de/ - IT Beratung, Softwareentwicklung, Remotesupport -
Es ist tatsächlich leider verwirrend... :)
Die Sortierung des Bohrprofils muss nach Tiefe der Hauptschichten erfolgen (absteigend). Die zugehörige Layer-ID kann sich bei einer späteren Bearbeitung des Profils ändern, wenn mitten drin eine neue Schicht angelegt wird - siehe Layer-ID 3 in der Beispieltabelle. Damit entspricht die aufsteigend sortierte Layer-ID nicht mehr der absteigedenn Reihenfolge der Tiefe:
Proj Lok Int Layer SubLay Tiefe
p1 1 0 0 0 52 Hauptschicht
p1 1 0 3 0 31 Hauptschicht zu einem späteren Zeitpunkt eingefügt
p1 1 0 2 0 24 Hauptschicht
p1 1 0 2 1 NULL Unterschicht
p1 1 0 2 2 27 Unterschicht
p1 1 0 2 3 NULL UnterschichtHauptschicht 2 hat in dem Beispiel den Hauptschichten-Eintrag und 3 Unterschichten-Einträge. Diese Unterschichten-Einträge hängen an der Layer-ID (=2) und sind gemäß SubLayer-ID aufsteigend zu sortieren.
-
Dies wären ein paar Inserts für die verschiedenen Situationen, in den neue Einträge durch die Anwendungslogik sehr wahrscheinlich generiert werden. @-Deklarationen repräsentieren Variablen, die sich aus der jeweiligen Eingabe-Maske bzw. der Bohrung ergeben, welche über die Eingabemaske angesprochen ist:
-- zugrundeliegende ANWENDUNGSLOGIK verbunden mit Daten-Eingabemasken
-- #1 Eingabe des ersten Datensatzes eines neues Bohrprofils
-- mit @depthto=251.07, @strat='toe', @petro='fS(T)'
-- Existiert bereits ein Bohrprofil für die Bohrung (@prj_id='4E2EF9' / @locid=503) ?
-- TRUE: @intv = 1 + select max(intv) from geodin_loc_s3schdat
-- where prj_id=@prj_id and locid=@locid
-- FALSE: intv=0
--
-- Für den Fall TRUE:
insert into geodin_loc_s3schdat (prj_id, locid, recid, intv, layerid, layercntr, depthto, sart, strat, petro, ...)
values(@prj_id, @locid, @recid, @intv, 0, 0, @depthto, NULL, @strat, @petro, ...)
-- #2 Eingabe einer neuen Hauptschicht für Bohrung (@prj_id='4E2EF9' / @locid=503)
-- und Interpretations-ID @intv=2
-- mit @depthto=251.07, @strat='toe', @petro='fS(T)'
-- @recid = 1 + select max(recid) from geodin_loc_s3schdat
-- where prj_id=@prj_id and locid=@locid and intv = @intv
-- @layerid = 1 + select max(layerid) from geodin_loc_s3schdat
-- where prj_id=@prj_id and locid=@locid and intv = @intv
insert into geodin_loc_s3schdat (prj_id, locid, recid, intv, layerid, layercntr, depthto, sart, strat, petro, ...)
values(@prj_id, @locid, @recid, @intv, @layerid, 0, @depthto, NULL, @strat, @petro, ...)
-- #3 Eingabe einer neuen Unterschicht für Bohrung (@prj_id='4E2EF9' / @locid=503), Interpretations-ID @intv=2,
-- mit @layerid=2, @depthto=Null, @sart='bnd', @strat=NULL, @petro='T'
-- @recid = 1 + select max(recid) from geodin_loc_s3schdat
-- where prj_id=@prj_id and locid=@locid and intv=@intv
-- @layercntr = 1 + select max(layercntr) from geodin_loc_s3schdat
-- where prj_id=@prj_id and locid=@locid and intv=@intv and layerid=@layerid
insert into geodin_loc_s3schdat (prj_id, locid, recid, intv, layerid, layercntr, depthto, sart, strat, petro, ...)
values(@prj_id, @locid, @recid, @intv, @layerid, @layercntr, @depthto, @sart, @strat, @petro, ...)
- Bearbeitet thorskilde Mittwoch, 21. April 2021 14:04
-
Hi,
sorry. Aber die Anforderung ist doch eigentlich recht klar.
Poste bitte INSERT INTO Statements für exakt die Daten (ohne Parameter, ohne Verweise auf irgendwelche Masken, ohne irgendwas anderes außer den reinen Werten), die in deinem Beispiel im ersten Posting ganz oben ausgegeben werden.
INSERT INTO geodin_loc_s3schdat( prj_id, locid, recid, intv, layerid, layercntr, depthto, sart, strat, petro ) VALUES ( 1, 2, 3, 4, 5, x, y, a, b, 0 )
Sowas halt. Nur natürlich mit den richtigen Daten.
Und nochmal: Wir brauchen exakt die Daten, die in deinem Beispiel dann "korrekt" sortiert ausgegeben werden können. Nur so ist es uns möglich, dein Problem nachvollziehen und eine Lösung erarbeiten zu können.
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET (2001-2018)
https://www.asp-solutions.de/ - IT Beratung, Softwareentwicklung, Remotesupport -
Alles klar, sorry for die lange Leitung:
insert into geodin_loc_s3schdat (prj_id, locid, recid, intv, layerid, layercntr, depthto, sart, strat, petro)
values
('4E2EF9', 503, 1, 0, 1, 0, 135.5, NULL, 'toe', 'fS(T)'),
('4E2EF9', 503, 2, 0, 2, 0, 10.1, NULL, 'toe', 'fS(T)'),
('4E2EF9', 503, 3, 0, 3, 0, -26.3, Null, 'toe', 'fS(T)'),
('4E2EF9', 503, 4, 0, 3, 1, Null, 'lg', 'toe', '^st'),
('4E2EF9', 503, 5, 0, 3, 2, 0.2, 'bnd', 'toe', 'fS(T)'),
('4E2EF9', 503, 6, 0, 4, 0, 35.5, NULL, 'toe', 'fS(T)'),
('4E2EF9', 503, 7, 0, 5, 0, -55.9, NULL, 'tuo', 'fS(T)'),
('4E2EF9', 503, 8, 0, 6, 0, 62.0, NULL, 'toe', 'fS(T)'),
('4E2EF9', 503, 9, 0, 6, 1, Null, 'brk', 'toe', 'fS(T)'),
('4E2EF9', 503, 10, 0, 6, 2, Null, 'lg', 'toe', 'fS(T)'),
('4E2EF9', 503, 11, 0, 7, 0, -89.4, NULL, 'krb', 'fS(T)'),
('4E2EF9', 503, 12, 0, 8, 0, -216.7, NULL, 'kra', 'fS(T)'),
('4E2EF9', 503, 13, 0, 9, 0, -134.9, NULL, 'krc', 'fS(T)'),
('4E2EF9', 503, 14, 0, 6, 3, 73.8, 'brk', 'toe', 'fS(T)'),
('4E2EF9', 503, 1, 1, 1, 0, 135.5, NULL, 'toe', 'fS(T)'),
('4E2EF9', 503, 2, 1, 2, 0, 12.6, NULL, 'toe', 'fS(T)'),
('4E2EF9', 503, 3, 1, 3, 0, -26.3, Null, 'toe', 'fS(T)'),
('4E2EF9', 503, 4, 1, 3, 1, Null, 'lg', 'toe', '^st'),
('4E2EF9', 503, 5, 1, 4, 0, 37.0, NULL, 'toe', 'fS(T)'),
('4E2EF9', 503, 6, 1, 5, 0, -55.9, NULL, 'tuo', 'fS(T)'),
('4E2EF9', 503, 7, 1, 6, 0, -89.4, NULL, 'krb', 'fS(T)'),
('4E2EF9', 503, 8, 1, 7, 0, -216.7, NULL, 'krc', 'fS(T)'),
('4E2EF9', 503, 9, 1, 8, 0, -134.9, NULL, 'kra', 'fS(T)'),
('4E2EF9', 503, 10, 1, 9, 0, 62.0, NULL, 'toe', 'fS(T)'),
('4E2EF9', 503, 11, 1, 6, 1, Null, 'lg', 'toe', 'fS(T)'),
('4E2EF9', 503, 12, 1, 6, 2, Null, 'lg', 'toe', 'fS(T)'),
('4E2EF9', 503, 13, 1, 6, 3, 73.8, 'brk', 'toe', 'fS(T)'),
('H2L99G', 3, 1, 0, 1, 0, 7.5, NULL, 'qa', 'fS(T)'),
('H2L99G', 3, 2, 0, 2, 0, -19.7, Null, 'qh-p', 'kgS'),
('H2L99G', 3, 3, 0, 3, 0, 4.9, NULL, 'qh', '(lhm),(hfS(T))'),
('H2L99G', 3, 1, 1, 1, 0, 7.0, NULL, 'qy', 'fS(T)'),
('H2L99G', 3, 2, 1, 2, 0, 5.3, NULL, 'qh', '(lhm),(hfS(T))'),
('H2L99G', 3, 3, 1, 3, 0, -19.7, Null, 'qh-p', 'kgS'),
('H2L99G', 3, 4, 1, 2, 1, Null, 'lg', Null, Null),
('H2L99G', 3, 5, 1, 4, 0, 8.2, Null, 'qhy', 'Af')- Bearbeitet thorskilde Mittwoch, 21. April 2021 15:55
-
Dann gib bei der Sortierung "order by [depthto] desc" an.
Ergänzen kannst du das ggf. mit "nulls first/last" je nach Bedeutung des Inhalts.
- Bearbeitet thorskilde Mittwoch, 21. April 2021 15:55
-
Alles klar, sorry for die lange Leitung:
Kein Ding.
Aber das sind ja nicht die Daten, die in deiner Beispieltabelle im ersten Posting sortiert ausgegeben werden.
Daher bräuchten wir dann noch das gewünschte, sortierte Ergebnis, basiernd exakt auf den jetzt im INSERT INTO Statement angegebenen Beispieldaten. Nur so können wir prüfen, welche Sortierungsangaben nun korrekt wären.
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET (2001-2018)
https://www.asp-solutions.de/ - IT Beratung, Softwareentwicklung, Remotesupport -
Das wäre das korrekte Abfrageergebnis im csv-Format. Kann man in Excel sicher leichter anschauen.
PRJ_ID;LOCID;RECID;INTV;LAYERID;LAYERCNTR;DEPTHTO;SART;STRAT;PETRO
4E2EF9;503;1;0;1;0;135,5;NULL;toe;fS(T)
4E2EF9;503;8;0;6;0;62;NULL;toe;fS(T)
4E2EF9;503;9;0;6;1;NULL;brk;toe;fS(T)
4E2EF9;503;10;0;6;2;NULL;lg;toe;fS(T)
4E2EF9;503;14;0;6;3;73,8;brk;toe;fS(T)
4E2EF9;503;6;0;4;0;35,5;NULL;toe;fS(T)
4E2EF9;503;2;0;2;0;10,1;NULL;toe;fS(T)
4E2EF9;503;3;0;3;0;-26,3;NULL;toe;fS(T)
4E2EF9;503;4;0;3;1;NULL;lg;toe;^st
4E2EF9;503;5;0;3;2;0,2;bnd;toe;fS(T)
4E2EF9;503;7;0;5;0;-55,9;NULL;tuo;fS(T)
4E2EF9;503;11;0;7;0;-89,4;NULL;krb;fS(T)
4E2EF9;503;13;0;9;0;-134,9;NULL;krc;fS(T)
4E2EF9;503;12;0;8;0;-216,7;NULL;kra;fS(T)
4E2EF9;503;1;1;1;0;135,5;NULL;toe;fS(T)
4E2EF9;503;10;1;9;0;62;NULL;toe;fS(T)
4E2EF9;503;5;1;4;0;37;NULL;toe;fS(T)
4E2EF9;503;2;1;2;0;12,6;NULL;toe;fS(T)
4E2EF9;503;3;1;3;0;-26,3;NULL;toe;fS(T)
4E2EF9;503;4;1;3;1;NULL;lg;toe;^st
4E2EF9;503;6;1;5;0;-55,9;NULL;tuo;fS(T)
4E2EF9;503;7;1;6;0;-89,4;NULL;krb;fS(T)
4E2EF9;503;11;1;6;1;NULL;lg;toe;fS(T)
4E2EF9;503;12;1;6;2;NULL;lg;toe;fS(T)
4E2EF9;503;13;1;6;3;73,8;brk;toe;fS(T)
4E2EF9;503;9;1;8;0;-134,9;NULL;kra;fS(T)
4E2EF9;503;8;1;7;0;-216,7;NULL;krc;fS(T)
H2L99G;3;1;0;1;0;7,5;NULL;qa;fS(T)
H2L99G;3;3;0;3;0;4,9;NULL;qh;(lhm),(hfS(T))
H2L99G;3;2;0;2;0;-19,7;NULL;qh-p;kgS
H2L99G;3;5;1;4;0;8,2;NULL;qhy;Af
H2L99G;3;1;1;1;0;7;NULL;qy;fS(T)
H2L99G;3;2;1;2;0;5,3;NULL;qh;(lhm),(hfS(T))
H2L99G;3;4;1;2;1;NULL;lg;NULL;NULL
H2L99G;3;3;1;3;0;-19,7;NULL;qh-p;kgS -
Noch mal langsam zum mitschreiben:
- Du zeigst immer noch nicht deine eigentliche Anfrage.
- Eine Order by kann durchaus mehere Felder in unterschiedlicher Folge: f1, f2 desc, f3, f4, f5 descDas ist dann immer noch keine komplexe Sortierung.
- Bearbeitet Der Suchende Mittwoch, 21. April 2021 17:23
-
Wir missverstehen uns. Ich habe leider keine Idee, wie ich eine solche Abfrage angehen kann.
Die Abfrage:
select * from geodin_loc_s3schdat
order by prj_id, locid, intv, depthfrom descsortiert mir nach der Tiefe. Das wirft das Problem auf, dass bei den Unterschichten z.T. 'depthto'-Werte stehen, die nichts mit der Sortierreihenfolge der Hauptschichten zu tun haben aber dadurch erfasst werden - ganz davon abgesehen, dass bei den meisten Unterschichten depthto = Null ist. Die Reihenfolge der Unterschichten ist durch layercntr vorgegeben.
Eine Hauptschicht, welche n Unterschichten besitzt ist ausschließlich über die die Layerid mit den Unterschichten verknüpft. Prj_id, locid sowie intv sind bei Haupt- und Nebenschichten natürlich auch gleich.
Die korrekte Zuordnung von Unterschichten zu ihren Hauptschichten habe ich bisher nur durch ein Python-Skript gelöst, in dem eine neue Sortier-Hilfsspalte in das Dataframe eingefügt wird und im ersten Schritt alle Tiefenangaben der Hauptschichten hineinkopiert werden. Dann wird über alle Unterschichten (layercntr<>0) iteriert und nach der zugehörigen Hauptschicht (gleiche prj_id, loc_id, intv, layerid) gesucht wird. Der Tiefenwert 'depthto' dieser Hauptschicht wird dann in die Sortier-Hilfsspalte in der Zeile der Unterschicht kopiert.
Am Ende enthält die Sortierhilfsspalte bei den Unterschichten die gleichen Tiefenwerte, wie die jeweiligen Hauptschichten und ich kann nun die abschließende Sortierung nach
prj_id, locid, intv, Tiefen-Werte in der Sortier-Hilfsspalte, layercntr
durchführen.
Ich möchte mit meiner Frage gern wissen, ob man möglicherweise eine komplexere Abfrage stricken kann oder ggf. in ähnlicher Weise auf eine Stored Prozedur (T-SQL oder Python) zurückgreifen müsste, wenn man es datenbankseitig lösen möchte.
Hoffentlich ist es jetzt klarer. Eine Abfrage die 'noch nicht ganz, wie erwartet funktioniert', kann ich leider nicht bieten.
- Bearbeitet thorskilde Mittwoch, 21. April 2021 18:18
-
Du kannst eine Prozedur erstellen, die genau dieses tut.
Zuerst deklarierst du eine temporäre Tabelle:
https://docs.microsoft.com/de-de/sql/relational-databases/in-memory-oltp/faster-temp-table-and-table-variable-by-using-memory-optimization?view=sql-server-ver15Dann berechnest du deine Beziehungen und fügst die Daten in die temporäre Tabelle ein.
Zum Schluss übergibst du den Inhalt der temporären Tabelle, sortiert, an den Aufrufer.Da wir mit deinen spezifischen Bezeichungen mangels Kenntnis nicht zurecht kommen, ist halt eine Beschreibung der Tabellen und der Beziehungen wichtig. Sonst kann man nur pauschale Empfehlungen geben:
with CalcTable as ( select f1, f2, calcformel as f3, coalesce(f4, 0) as f4 from mytable ) select * from CalcTable order by f1, f2, f3 desc
Da kannst du alles Berechnen was du benötigst, mittels Coalesce(feld, wert) kannst du NULL's ersetzen.