Benutzer mit den meisten Antworten
Ermitteln eines Folgedatensatzes innerhalb einer Sortierung abhängig von Kriterien

Frage
-
Hallo zusammen,
ich habe folgende Tabelle eines Werkskalenders für verschiedene Werke:
CREATE TABLE [dbo].[Werkskalender]( [Werk-ID] [nvarchar](4) NOT NULL, [Datum] [varchar](10) NOT NULL, [Arbeitstag-Flag] [char](1) NOT NULL ) ON [PRIMARY] GO SET ANSI_PADDING ON GO INSERT [dbo].[Werkskalender] ([Werk-ID], [Datum], [Arbeitstag-Flag]) VALUES (N'1001', N'20130101', N'0') GO INSERT [dbo].[Werkskalender] ([Werk-ID], [Datum], [Arbeitstag-Flag]) VALUES (N'1001', N'20130102', N'1') GO INSERT [dbo].[Werkskalender] ([Werk-ID], [Datum], [Arbeitstag-Flag]) VALUES (N'1001', N'20130103', N'1') GO INSERT [dbo].[Werkskalender] ([Werk-ID], [Datum], [Arbeitstag-Flag]) VALUES (N'1001', N'20130104', N'1') GO INSERT [dbo].[Werkskalender] ([Werk-ID], [Datum], [Arbeitstag-Flag]) VALUES (N'1001', N'20130105', N'0') GO INSERT [dbo].[Werkskalender] ([Werk-ID], [Datum], [Arbeitstag-Flag]) VALUES (N'1001', N'20130106', N'0') GO INSERT [dbo].[Werkskalender] ([Werk-ID], [Datum], [Arbeitstag-Flag]) VALUES (N'1001', N'20130107', N'1') GO INSERT [dbo].[Werkskalender] ([Werk-ID], [Datum], [Arbeitstag-Flag]) VALUES (N'1001', N'20130108', N'1') GO INSERT [dbo].[Werkskalender] ([Werk-ID], [Datum], [Arbeitstag-Flag]) VALUES (N'1001', N'20130109', N'1') GO INSERT [dbo].[Werkskalender] ([Werk-ID], [Datum], [Arbeitstag-Flag]) VALUES (N'1001', N'20130110', N'1') GO INSERT [dbo].[Werkskalender] ([Werk-ID], [Datum], [Arbeitstag-Flag]) VALUES (N'1001', N'20130111', N'1') GO INSERT [dbo].[Werkskalender] ([Werk-ID], [Datum], [Arbeitstag-Flag]) VALUES (N'1001', N'20130112', N'0') GO INSERT [dbo].[Werkskalender] ([Werk-ID], [Datum], [Arbeitstag-Flag]) VALUES (N'1001', N'20130113', N'0') GO INSERT [dbo].[Werkskalender] ([Werk-ID], [Datum], [Arbeitstag-Flag]) VALUES (N'1001', N'20130114', N'1') GO INSERT [dbo].[Werkskalender] ([Werk-ID], [Datum], [Arbeitstag-Flag]) VALUES (N'1001', N'20130115', N'1') GO INSERT [dbo].[Werkskalender] ([Werk-ID], [Datum], [Arbeitstag-Flag]) VALUES (N'1001', N'20130116', N'1') GO INSERT [dbo].[Werkskalender] ([Werk-ID], [Datum], [Arbeitstag-Flag]) VALUES (N'1001', N'20130117', N'1') GO INSERT [dbo].[Werkskalender] ([Werk-ID], [Datum], [Arbeitstag-Flag]) VALUES (N'1001', N'20130118', N'1') GO INSERT [dbo].[Werkskalender] ([Werk-ID], [Datum], [Arbeitstag-Flag]) VALUES (N'1001', N'20130119', N'0') GO INSERT [dbo].[Werkskalender] ([Werk-ID], [Datum], [Arbeitstag-Flag]) VALUES (N'1001', N'20130120', N'0') GO INSERT [dbo].[Werkskalender] ([Werk-ID], [Datum], [Arbeitstag-Flag]) VALUES (N'1001', N'20130121', N'1') GO INSERT [dbo].[Werkskalender] ([Werk-ID], [Datum], [Arbeitstag-Flag]) VALUES (N'1001', N'20130122', N'1') GO INSERT [dbo].[Werkskalender] ([Werk-ID], [Datum], [Arbeitstag-Flag]) VALUES (N'1001', N'20130123', N'1') GO INSERT [dbo].[Werkskalender] ([Werk-ID], [Datum], [Arbeitstag-Flag]) VALUES (N'1001', N'20130124', N'1') GO INSERT [dbo].[Werkskalender] ([Werk-ID], [Datum], [Arbeitstag-Flag]) VALUES (N'1001', N'20130125', N'1') GO INSERT [dbo].[Werkskalender] ([Werk-ID], [Datum], [Arbeitstag-Flag]) VALUES (N'1001', N'20130126', N'0') GO INSERT [dbo].[Werkskalender] ([Werk-ID], [Datum], [Arbeitstag-Flag]) VALUES (N'1001', N'20130127', N'0') GO INSERT [dbo].[Werkskalender] ([Werk-ID], [Datum], [Arbeitstag-Flag]) VALUES (N'1001', N'20130128', N'1') GO INSERT [dbo].[Werkskalender] ([Werk-ID], [Datum], [Arbeitstag-Flag]) VALUES (N'1001', N'20130129', N'1') GO INSERT [dbo].[Werkskalender] ([Werk-ID], [Datum], [Arbeitstag-Flag]) VALUES (N'1001', N'20130130', N'1') GO INSERT [dbo].[Werkskalender] ([Werk-ID], [Datum], [Arbeitstag-Flag]) VALUES (N'1001', N'20130131', N'1') GO
Ziel ist es nun, für jeden Datensatz den jeweils nächsten Arbeitstag (Arbeitstag-Flag = 1) zu ermitteln, falls im aktuellen Datensatz Arbeitstag-Flag = 0 ist. Man müsste also so lange zum nächsten Datensatz springen, bis dieser nicht mehr Flag=0 hat und dann das Datum dieses Datensatzes im ursprünglichen Datensatz vermerken.
Die Zieltabelle hätte demnach folgendes Format.
Werk-ID, Datum, Arbeitstag-Flag, Datum_Arbeitstag_Korrektur
1, 20130101, 0, 20130102
1, 20130102, 1, 20130102
1, 20130103, 1, 20130103
1, 20130104, 1, 20130104
1, 20130105, 0, 20130107
1, 20130106, 0, 20130107
1, 20130107, 1, 20130107
Vermutlich kann man etwas mit Window-Fuktionen machen, mir fehlt aber eine Idee, wie ich dieses dynamische Fenster definieren kann... Kann jemand helfen?
Viele Grüße
Axel
- Bearbeitet Axel Bergmann Donnerstag, 17. Oktober 2013 10:18 Codeblock ergänzt
Antworten
-
Hallo Axel,
das bei Dir "Datum" ein varchar(10) ist, ist hier nicht so optimal, besser wäre ein Integer oder Date Typ. Dann kannst Du es mit einem einfachen Subselect lösen:
SELECT * ,(SELECT TOP 1 SUB.[Datum] FROM [dbo].[Werkskalender] AS SUB WHERE SUB.[Arbeitstag-Flag] = 1 AND SUB.Datum > WK.Datum ORDER BY SUB.Datum ASC) AS NextWorkingDay FROM [dbo].[Werkskalender] AS WK
Also: Ermittle den nächsten echt größeren Datumswert mit Arbeitstag-Flag = 1, davon aber nur den ersten nach aufsteigender Sortierung. Noch einen passenden Index dazu und dann sollte es gut laufen.
Olaf Helper
[ Blog] [ Xing] [ MVP]- Als Antwort markiert Axel Bergmann Donnerstag, 17. Oktober 2013 11:40
Alle Antworten
-
Hallo Axel,
das bei Dir "Datum" ein varchar(10) ist, ist hier nicht so optimal, besser wäre ein Integer oder Date Typ. Dann kannst Du es mit einem einfachen Subselect lösen:
SELECT * ,(SELECT TOP 1 SUB.[Datum] FROM [dbo].[Werkskalender] AS SUB WHERE SUB.[Arbeitstag-Flag] = 1 AND SUB.Datum > WK.Datum ORDER BY SUB.Datum ASC) AS NextWorkingDay FROM [dbo].[Werkskalender] AS WK
Also: Ermittle den nächsten echt größeren Datumswert mit Arbeitstag-Flag = 1, davon aber nur den ersten nach aufsteigender Sortierung. Noch einen passenden Index dazu und dann sollte es gut laufen.
Olaf Helper
[ Blog] [ Xing] [ MVP]- Als Antwort markiert Axel Bergmann Donnerstag, 17. Oktober 2013 11:40