Benutzer mit den meisten Antworten
Cursorproblem ohne Cursor lösen

Frage
-
Hi Community,
hier mal ein ganz theoretisches Problem.
Ziel ist, in einer Tabelle eine laufende Summe mitzuspeichern, die Bereits bei der Eingabe der Daten geschrieben wird. (siehe Codebeispiel)
Das klappt auch soweit wunderbar, solange jedesmal lediglich ein Datensatz importiert wird.
Ich wurde im Rahmen einer Schulung darauf angesprochen, konnte natürlich auch Lösungen präsentieren.
1. Das ganze über einen Cursor erledigen
2. Im Nachlauf nochmal über die Tabelle gehen.
Ich suche aber gerne nach eleganteren Lösungen - hat vielleicht jemand eine Idee, wie ich auch mehrere Datensätze direkt beim Import richtig einfügen kann.
Den Code habe ich auf das Wesentliche reduziert, danke für Eure Antworten
Roland
CREATE TABLE [dbo].[tblStamm]( [st_ID] [int] IDENTITY(1,1) NOT NULL, [st_Einzahlung] [float] NOT NULL, [st_Bestand] [float] NOT NULL, CONSTRAINT [PK_tblSta] PRIMARY KEY CLUSTERED ( [st_ID] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO CREATE TABLE [dbo].[tblImport]( [imp_ID] [int] IDENTITY(1,1) NOT NULL, [imp_Einzahlung] [float] NOT NULL, CONSTRAINT [PK_tblImport] PRIMARY KEY CLUSTERED ( [imp_ID] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO INSERT INTO tblImport ( imp_Einzahlung ) VALUES (10),(10),(20) INSERT INTO [tblStamm] ( [st_Einzahlung], [st_Bestand] ) SELECT imp_Einzahlung, imp_Einzahlung + (SELECT ISNULL(Sum((st_Einzahlung)),0) FROM tblStamm) FROM tblImport ORDER BY imp_ID Update tblStamm SET st_Bestand = (SELECT SUM(st_Einzahlung) FROM tblStamm s WHERE s.st_ID <= tblStamm.st_ID) SELECT * FROM tblImport SELECT * FROM tblStamm /* TRUNCATE TABLE tblStamm TRUNCATE TABLE tblImport */ /* DROP TABLE tblStamm DROP TABLE tblImport */
It's no problem, it's just the syntax
Antworten
-
- Als Antwort markiert Ionut DumaModerator Donnerstag, 10. Juli 2014 08:45
Alle Antworten
-
Hallo Roland,
Welche Version des Sql Server verwendest Du? Wenn es 2012 oder 2014 ist, dann kannst Du die laufende Summe "on the fly" mit der neuen SUM OVER Funktion abfragen, statt es in der Tabelle zu speichern; liefert natürlich nur dann richtige Ergebnisse, wenn man die Daten nicht filtert.
SELECT *, SUM(st_Einzahlung) OVER (ORDER BY st_id) AS RunningSum FROM tblStamm ORDER BY st_id
Olaf Helper
[ Blog] [ Xing] [ MVP] -
Ab 2005 kann man es wenigstens über eine CTE realisieren, nicht so elegant, wie ab 2012, aber immerhin.
WITH NumberedRows AS (SELECT st_ID, st_Einzahlung, st_ID AS rn FROM dbo.tblStamm) SELECT d1.st_ID, d1.st_Einzahlung, SUM(d2.st_Einzahlung) AS RunningSum FROM NumberedRows AS d1 INNER JOIN NumberedRows AS d2 ON d2.rn < = d1.rn GROUP BY d1.st_ID, d1.st_Einzahlung ORDER BY d1.st_ID;
Wenn Du dann noch eine Spalte (Part) zur Partitionierung hast dann geht es mit einer Window Function:
WITH NumberedRows AS (SELECT Part, st_ID, st_Einzahlung, ROW_NUMBER() OVER (PARTITION BY Part ORDER BY st_ID) AS rn FROM dbo.tblStamm) SELECT d1.Part, d1.st_ID, d1.st_Einzahlung, SUM(d2.st_Einzahlung) AS MovSUM FROM NumberedRows AS d1 INNER JOIN NumberedRows AS d2 ON d2.Part = d1.Part AND d2.rn < = d1.rn GROUP BY d1.Part, d1.st_ID, d1.st_Einzahlung ORDER BY d1.Part, d1.st_ID;
Die Lösung von Olaf (ab 2012) ist aber auch für die Partitionierung viel einfacher.
SUM(st_Einzahlung) OVER (PARTITION BY Part ORDER BY st_id) AS RunningSum
Einen schönen Tag noch,
Christoph
--
Microsoft SQL Server MVP - http://www.insidesql.org/blogs/cmu -
Hallo Olaf, Hallo Christoph,
erst mal Danke für Eure schnellen Antworten.
Allerdings gingen die etwas am Thema vorbei. In keiner der beiden Antworten erscheint die Importtabelle. Das mit der Running Sum ist ja eigentlich schon mit dem UPDATE abgehakt.
Mir ging es darum, ob ich schon beim Import die Datensätze fertig speichern kann, indem diese quasi nacheinander (Wie beim Cursor) geschrieben werden. Daher sollte die Lösung auf jeden Fall ein INSERT enthalten.
Gruß und schönes Wochenende
Roland
It's no problem, it's just the syntax
-
- Als Antwort markiert Ionut DumaModerator Donnerstag, 10. Juli 2014 08:45