![]() |
Leerer Datensatz bei SQL Abfrage
Ich habe eine Tabelle in der Datensätze stehen, die grundsätzlich 2 Preissummen mit unterschiedlichen Steuersätzen enthalten. Für den Report benötige ich aber die Summe über alle Datensätze nach Steuersatz sortiert. Dazu habe ich folgendes SQL Statement geschrieben:
Delphi-Quellcode:
Funktioniert zwar ganz gut, aber ich erhalte, wenn eine der Nettosummen 0 ist für diesen einen leeren Datensatz, so dass ich immer 2 Sätze in der Ergebnismenge habe. Jetzt habe ich auch versucht das obige SELECT - Statement in ein anderes SELECT Statement zu schachteln, das den leeren Satz wieder rausfiltert. Geschachtelte SELECT Anweisungen scheint lokal SQL aber nicht zu unterstützen, oder?
SELECT SUM(Netto1) AS SumNetto,
ST1 AS ST, SUM(MwST1) AS SummSteuer, SUM(Netto1)+SUM(MwSt1) AS Brutto WHERE Netto1 > 0 GROUP BY ST1 UNION SELECT SUM(Netto2) AS SumNetto, ST2 AS ST, SUM(MwST2) AS SummSteuer, SUM(Netto2)+SUM(MwSt2) AS Brutto WHERE Netto2 > 0 GROUP BY ST2 |
Meinst Du sowas mit verschachtelt ?
Zitat:
Code:
Dasselbe steht doch schon drin mit Netto1. Überschreibst Du Dir da nicht Dein SumNetto ???
SUM (Netto2) AS SumNetto
Gruß Hansa |
Hallo Hansa,
ich habe es so versucht:
Delphi-Quellcode:
Lokal SQL meldet dann, dass das zweite SELECT ungültig ist!?
SELECT [b]*[/b] FROM (
SELECT SUM(Netto1) AS SumNetto, ST1 AS ST, SUM(MwST1) AS SummSteuer, SUM(Netto1)+SUM(MwSt1) AS Brutto WHERE Netto1 > 0 GROUP BY ST1 UNION SELECT SUM(Netto2) AS SumNetto, ST2 AS ST, SUM(MwST2) AS SummSteuer, SUM(Netto2)+SUM(MwSt2) AS Brutto WHERE Netto2 > 0 GROUP BY ST2) WHERE ... Zitat:
|
Da hab ich noch was interessantes :
![]() Die Beispiele versteh sogar ich (fast). Gruß Hansa |
Hallo Mr. Spock 8)
Irgendwie vermisse ich hier SELECT-FROM Kombination. Also ich meine nach jedem SELECT sollte irgendwann auch FROM- Schlüsselwort auftauchen. Kurz vorbeigeschaut und schon weg... Gruß Paul Jr. |
Hallo Paul Jr,
schön wieder mal was von dir zu hören: Du hast natürlich recht, war ein Fehler beim hinschreiben im geposteten Code. Im Programm habe ich es richtig:
Delphi-Quellcode:
SELECT SUM(Netto1) AS SumNetto,
ST1 AS ST, SUM(MwST1) AS SummSteuer, SUM(Netto1)+SUM(MwSt1) AS Brutto [b]FROM RechListe[/b] WHERE Netto1 > 0 GROUP BY ST1 UNION SELECT SUM(Netto2) AS SumNetto, ST2 AS ST, SUM(MwST2) AS SummSteuer, SUM(Netto2)+SUM(MwSt2) AS Brutto [b]FROM RechListe[/b] WHERE Netto2 > 0 GROUP BY ST2 |
Also, Mr. Spock, deine SQL- Anweisung ist vollkommen richtig (unter Ms-SQL 2000)!
Ich habe Dein Problem nicht genau verstanden (welche Netto- Summe ist gleich 0? usw...) Gruß Paul Jr. |
Hallo Paul Jr,
die Datensätze in der Tabelle sind Rechnungen. Manche Rechnungen enthalten Positionen sowohl mit 7% als auch mit 16% Steuer. Wenn ich Rechnungen auswähle, bei denen mindestens eine von diesen Positionen zu beiden Steuersätzen enthält ist alles OK. Ist aber nur ein Steuersatz enthalten, erhalte ich trotzdem 2 Sätze in der Ergebnismenge. Der erste ist aber leer, hat also keinen Eintrag in irgendeinem Feld. Dieser Leersatz stört jetzt meine Ausgabe. |
Hallo Mr.Spock,
jetzt verstehe ich! Nun ja, so "auf die schnelle" weiß ich nicht... vielleicht probiere mit WHERE-Bedingung... z.B.: WHERE (Netto2 > 0) AND (NOT (Mwst2 is NULL)) Na ja Mr. Spock, dass war für's heute... kämpfe weiter... Ich zeige mich bald wieder Tschüß Paul Jr. |
Hi MrSpock,
wie das da aussieht ist das wieder so eine klassische Frage : "Macht das die DB, oder soll das mein Programm machen :?: " Ich habe zwar noch kein so richtiges Gefühl für die SQL Geschichten, aber in diesem Fall bin ich mir trotzdem ziemlich sicher, daß ich das da in Delphi machen würde. Ich mache, bzw. werde so etwas mit einem kleinen Array machen, d.h. zu jeder Position halte ich den Mwst.-Satz fest. Wenn ich sowieso die Rechn.-Positionen anzeigen /drucken muß, muß ich doch nur den Pos.-Betrag in einer Variablen dazuaddieren. Für 7 und 16% braucht man doch nur 2 real-Variablen. Eine Prüfung darauf ob eine / zwei <> 0 sind, ist wohl das kleinste Übel. Aber wahrscheinlich hast Du andere Gründe, es nicht so zu machen. Gruß Hansa |
Hallo Hansa,
Zitat:
Funktioniert, ist aber nicht gerade elegant. |
Hallo MrSpock,
so ungefähr habe ich mir das gedacht. Ich habe sogar an die Qreports gedacht :mrgreen: , da ich mit berechneteten Feldern auch Schwierigkeiten hatte. Hierzu müßte hier ein Thread vorhanden sein. Vielleicht sollten wir den wieder zum Leben erweckenn, also ich jedenfalls habe das ganze zurückgestellt, da ich nicht weiterkam. Werde das auch jetzt mal suchen, um zu sehen, wo ich damals stehenblieb. Ich glaube aber trotzdem nicht, daß solch eine verschachtelte SELECT-Konstruktion nötig ist. Gruß Hansa |
Hallo MrSpock
Ich bin mir nicht sicher, ob ich Dein Problem richtig verstanden habe. Wenn Du zwei Datensätze möchtes, das aber nur, wenn im betreffenden Netto-Feld ein Wert steht, dann denke ich, das ist ein klarer Fall für den Einsatz von Having. Im SQL-Server sieht das wie folgt aus:
Code:
Im Gegensatz zum Where wird bei Having die Gruppierung berücksichtigt. Es gibt aber noch eine andere Schreibweise von HAVING. Anstelle der SUM-Funktion muss die Alias-Variable angegeben werden. SQLAnywhere macht das zum Beispiel. In diesem Falle sieht das dann so aus: HAVING SumNetto > 0
SELECT SUM(Netto1) AS SumNetto,
ST1 AS ST, SUM(MwST1) AS SummSteuer, SUM(Netto1)+SUM(MwSt1) AS Brutto FROM RechListe GROUP BY ST1 HAVING SUM(Netto1) > 0 UNION SELECT SUM(Netto2) AS SumNetto, ST2 AS ST, SUM(MwST2) AS SummSteuer, SUM(Netto2)+SUM(MwSt2) AS Brutto FROM RechListe GROUP BY ST2 HAVING SUM(Netto2) > 0 Gruss Xaver |
Das von Xaver klingt plausibel. Werde mir jetzt doch mal ein reines SQL-Buch kaufen.
@xbu58 : Wo steht denn sowas verständlich drin ? Was ich im Internet finde ist zu knapp gehalten. Habe meinen UB-Ausweis upgedatet, aber die haben nur uralten Schrott. 10 Jahre ist da noch fast das jüngste. Aber das ganze mit SQL wird ja immer komplizierter. Ich habe deshalb mal meinen Ansatz weiterverfolgt. Das Problem aus dem anderen Thread kam anscheinend daher, daß das dataset nicht active auf true war. Übung macht den Meister. Jetzt geht das schon, wie es soll. Meine Methode müßte so schon funktionieren. Aber nun muß ich mich noch einmal von vorne in QR einarbeiten. Bei einer Expression mit einem Datensatz und einer Multiplikation geht es jedenfalls. :mrgreen: Eventuelle Werte mit 0 dürften sich doch auch leicht ausblenden lassen. Gruß Hansa |
Hallo xbu58,
vielen Dank, genau das war es! Der leere Satz ist weg. Muss ich mir einprägen: HAVING, HAVING, HAVING .... Jetz hab ich's. :mrgreen: |
Hallo MrSpock
Feudt mich, dass ich einem Moderator etwas zeigen konnte :dancer: Überigens gibts beim Union noch eine Tücke! Wenn Du zwei Datensäzte aus beiden Statements hast, die genau gleich sind, wird einer unterdrückt. Das kann manchmal erwünscht sein aber in Deinem Fall glaube ich nicht. Du kannst das unterdrücken, indem Du UNION ALL schreibst. Wenn das nicht geht, kannst Du immer noch eine Konstante in beiden Script einfügen, welche jedoch unterschiedlich ist.
Code:
Hoffe das geht.
SELECT Typ=1
... UNION SELECT Typ=2 .. Gruss Xaver |
Hi,
wußte doch, ich brauche ein gutes Buch für den Kram, das wird ja immer doller, aber ich nehme an demnächst auch an solchen Klippen zu landen. Aber was ist denn jetzt, was spricht dafür das da so kompliziert direkt mit SQL zu machen ? Es geht doch nur darum, zwei Zahlen zu ermitteln :?: Man sollte den C/S-Traffic nicht übertreiben, das ist schon klar, aber solche verschachtelte Abfragen dienen doch wohl auch nicht der Performance, zumal zumindest in diesem Falle wohl sowieso alle gewünschten Zahlen bereit stehen. Gruß Hansa :wiejetzt: |
Hallo Hansa
Zu Deiner Frage wo das drin steht. Na wenn ich das Dir sage, kann ich mit meinem Wissen nicht mehr auftrumpfen :lol: . Ok, Spass bei seite. Es gibt ein sehr gutes SQL-Lehrbuch, das ich vor Jahren einmal gekauft habe. Ich habe es aber leider momentan nicht zur Hand, werde morgen nachsehen und die Angaben posten. Aber wie das so ist, kann man das meiste nur mit Erfahrung erlernen. Was aber auch sehr gut ist, ist die Hilfe vom Microsoft SQL-Server und SQLAnywhere. Die beschreiben die einzelnen Befehle sehr gut. Hier ein Beispiel aus dem SQLServer-Help
Code:
Wie Du siehst, wird sehr genau auf die einzelnen Optionen eingegangen. Und natürlich gibt es dazu noch jede Menge Links zu anderen Seite, welche einzelne Bereiche beschreiben.
SELECT
Ruft Zeilen aus der Datenbank ab und ermöglicht die Auswahl einer oder vieler Zeilen oder Spalten aus einer Tabelle oder aus zahlreichen Tabellen. Die vollständige Syntax der SELECT-Anweisung ist komplex, die Hauptklauseln können jedoch wie folgt zusammengefasst werden: SELECT select_list [ INTO new_table ] FROM table_source [ WHERE search_condition ] [ GROUP BY group_by_expression ] [ HAVING search_condition ] [ ORDER BY order_expression [ ASC | DESC ] ] Der UNION-Operator kann zwischen Abfragen verwendet werden, um ihre Ergebnisse zu einem einzigen Resultset zu kombinieren. Syntax SELECT statement ::= <query_expression> [ ORDER BY { order_by_expression | column_position [ ASC | DESC ] } [ ,...n ] ] [ COMPUTE { { AVG | COUNT | MAX | MIN | SUM } ( expression ) } [ ,...n ] [ BY expression [ ,...n ] ] ] [ FOR { BROWSE | XML { RAW | AUTO | EXPLICIT } [ , XMLDATA ] [ , ELEMENTS ] [ , BINARY BASE64 ] } ] [ OPTION ( < query_hint > [ ,...n ]) ] <query expression> ::= { <query specification> | (<query expression>) } [ UNION [ ALL ] < query specification | ( < query expression > ) [...n ] ] <query specification> ::= SELECT [ ALL | DISTINCT ] [ {TOP integer | TOP integer PERCENT} [ WITH TIES] ] <select_list> [ INTO new_table ] [ FROM {<table_source>} [,...n] ] [ WHERE <search_condition> ] [ GROUP BY [ALL] group_by_expression [,...n] [ WITH { CUBE | ROLLUP } ] ] [ HAVING <search_condition> ] Da die SELECT-Anweisung relativ komplex ist, werden detaillierte Syntaxelemente und Argumente nach Klauseln zusammengefasst aufgeführt: Gruss Xaver |
hehe, wenn Du weiter auftrumpfen willst, nur zu. Hab nichts dagegen, dann spare ich mir das Buch, Du hast die Arbeit und ich leg mich dann auf die --> :duck: Du hast ja schon gesagt, das solle ich machen. :chat:
|
Hallo Hansa
Also wirklich, Du bringst mich noch zum Schreien. Ich kann ja gar nicht so schnell antworten, wie Du Fragen stellst. :D (bin nur ein lansamer Schweizer) Als zu der Traffic. Grundsätzlich bin ich der Meinung, dass die Traffic auf den Server gehört. Dadurch kannst Du auch mit 500 MHz Workstation noch flott arbeiten. Besonders wichtig wird dies, wenn man von tausenden von Datensätzen spricht. Hier kann man mit inteligenten SQL-Scripts ohne weiteres Geschwindigkeitsvorteile von Faktor 3 bis 4 herausholen. Ich habe z.B. in einem Fall eine Tabelle, in der über 500'000 Datensäzte vorhanden sind. Wenn ich diese über Netz lade, um eine Jahresauswertung zu machen, kann ich gleich schlafen gehen. Wenn ich das jedoch vom Server erledigen lasse, dauerts max. 3 Min. Da siehst Du was es bringt. Gruss Xaver |
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:22 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz