Benutzer mit den meisten Antworten
String Spliten und dann daraus Anzahl bestimmte Datums herausgeben

Frage
-
Hallo,
ich habe in der Spalte feiertage in der Tabelle dbo.feiertag einen String, der bestimmte Einträge mit Komma getrennt beinhaltet. In den Einträgen sind auch Datums dabei.
Jetzt möchte ich gerne die Anzahl von Datums von einem bestimmten Jahr haben rausgeben.
Kann jemand mir vielleicht sagen, ob und wie ich das machen könnte?
Gruesse, NUNUI
Antworten
-
Hi,
Du solltest nicht mit kommaseparierten Werten in einer Spalte arbeiten, wenn Du die einzelnen Werte noch verarbeiten musst. Ändere dein Datenbankdesign lieber so, dass die Werte in einer separaten Tabelle stehen.
Da ich aber ehrlich gesagt nicht rauslesen kann, wie in deinem Fall was wo gespeichert ist, poste bitte das CREATE TABLE Statement für deine Tabelle, INSERT INTO Statements für die Beispieldaten und das gewünschte Ergebnis deiner Abfrage, basierend auf diesen Beispieldaten.
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET
http://www.asp-solutions.de/ - Consulting, Development
http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community- Als Antwort vorgeschlagen Dimitar DenkovMicrosoft contingent staff, Administrator Donnerstag, 29. Dezember 2016 14:17
- Als Antwort markiert Dimitar DenkovMicrosoft contingent staff, Administrator Freitag, 6. Januar 2017 11:07
-
Hallo,
dass das Tabellendesign so nicht sinnvoll ist, haben ja die anderen schon geschrieben.
Wenn Du SQL Server 2016 verwendest, kannst Du die STRING_SPLIT (Transact-SQL) Funktion zum Splitten und die TRY_CONVERT (Transact-SQL) Funktion zum sicheren Konvertieren verwenden.
Beispiel:
DECLARE @data varchar(8000) = 'Niedersachsen;01.01.2016;Neujahr;NJ;25.03.2016;Karfreitag;KF;28.03.2016;Ostermontag;OM;01.05.2016;Tag der Arbeit;TA;05.05.2016;Christi Himmelfahrt;CH;16.05.2016;Pfingstmontag;PM;03.10.2016;Tag der Deutschen Einheit;DA;25.12.2016;1. Weihnachtstag;1W;26.12.2016;2. Weihnachtstag;2W;01.01.2017;Neujahr;NJ;14.04.2017;Karfreitag;KF;17.04.2017;Ostermontag;OM;01.05.2017;Tag der Arbeit;TA;25.05.2017;Christi Himmelfahrt;CH;05.06.2017;Pfingstmontag;PM;03.10.2017;Tag der Deutschen Einheit;DA;31.10.2017;Reformationstag;RT;25.12.2017;1. Weihnachtstag;1W;26.12.2017;2. Weihnachtstag;2W'; ;WITH cte AS (SELECT SUB.value, TRY_CONVERT(datetime, SUB.value) AS Datum FROM STRING_SPLIT(@data, ';') AS SUB WHERE ISDATE(SUB.value) = 1) SELECT *, DATENAME(weekday, cte.Datum) FROM cte WHERE YEAR(cte.Datum) = 2016 AND DATENAME(weekday, cte.Datum) <> 'Sonntag'
Eine gute Performanz darf man hier aber nicht erwarten.
Olaf Helper
[ Blog] [ Xing] [ MVP]- Bearbeitet Olaf HelperMVP Dienstag, 27. Dezember 2016 18:00
- Als Antwort vorgeschlagen Dimitar DenkovMicrosoft contingent staff, Administrator Donnerstag, 29. Dezember 2016 14:17
- Als Antwort markiert Dimitar DenkovMicrosoft contingent staff, Administrator Freitag, 6. Januar 2017 11:07
Alle Antworten
-
Hi,
Du solltest nicht mit kommaseparierten Werten in einer Spalte arbeiten, wenn Du die einzelnen Werte noch verarbeiten musst. Ändere dein Datenbankdesign lieber so, dass die Werte in einer separaten Tabelle stehen.
Da ich aber ehrlich gesagt nicht rauslesen kann, wie in deinem Fall was wo gespeichert ist, poste bitte das CREATE TABLE Statement für deine Tabelle, INSERT INTO Statements für die Beispieldaten und das gewünschte Ergebnis deiner Abfrage, basierend auf diesen Beispieldaten.
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET
http://www.asp-solutions.de/ - Consulting, Development
http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community- Als Antwort vorgeschlagen Dimitar DenkovMicrosoft contingent staff, Administrator Donnerstag, 29. Dezember 2016 14:17
- Als Antwort markiert Dimitar DenkovMicrosoft contingent staff, Administrator Freitag, 6. Januar 2017 11:07
-
Hallo Stefan,
Die Tabelle wird wie folgt erzeugt:
CREATE TABLE [dbo].[feiertage]( [id] [int] IDENTITY(1,1) NOT NULL, [feiertage] [text] NULL, CONSTRAINT [PK_feiertage] PRIMARY KEY CLUSTERED ( [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] TEXTIMAGE_ON [PRIMARY]
Und der Text, was in der Spalte feiertage eingetragen ist (pro Bundesland):
Niedersachsen;01.01.2016;Neujahr;NJ;25.03.2016;Karfreitag;KF;28.03.2016;Ostermontag;OM;01.05.2016;Tag der Arbeit;TA;05.05.2016;Christi Himmelfahrt;CH;16.05.2016;Pfingstmontag;PM;03.10.2016;Tag der Deutschen Einheit;DA;25.12.2016;1. Weihnachtstag;1W;26.12.2016;2. Weihnachtstag;2W;01.01.2017;Neujahr;NJ;14.04.2017;Karfreitag;KF;17.04.2017;Ostermontag;OM;01.05.2017;Tag der Arbeit;TA;25.05.2017;Christi Himmelfahrt;CH;05.06.2017;Pfingstmontag;PM;03.10.2017;Tag der Deutschen Einheit;DA;31.10.2017;Reformationstag;RT;25.12.2017;1. Weihnachtstag;1W;26.12.2017;2. Weihnachtstag;2W
Und jetzt möchte ich Anzahl der Tage, die keine Sonntag sind, z.B. für das Jahr 2016 herausgeben.
Hoffe, könnte ich es einigermaßen verständlich erklären!
Gruesse, NUNUI
-
Hallo Nunui,
wie Stefan bereits geschrieben hat ist dein Tabellendesign eher ungeeignet dafür. Hier würde es sich anbieten drei Spalten zu nutzen
Datum (date)
Bundesland char(30)
Feiertagname char(20)
mit einem Primärschüssel über die Spalten Datum und Bundesland. Zudem wäre eine Dimensionstabelle mit Datumswerten hilfreich um die Vergleiche zu beschleunigen.
Benjamin Hoch
MCSE: Data Platform
MCSE: Data Management and Analytics
MCSA: SQL Server 2012/2014
MCSA: Windows Server 2012
Blog -
Hallo,
dass das Tabellendesign so nicht sinnvoll ist, haben ja die anderen schon geschrieben.
Wenn Du SQL Server 2016 verwendest, kannst Du die STRING_SPLIT (Transact-SQL) Funktion zum Splitten und die TRY_CONVERT (Transact-SQL) Funktion zum sicheren Konvertieren verwenden.
Beispiel:
DECLARE @data varchar(8000) = 'Niedersachsen;01.01.2016;Neujahr;NJ;25.03.2016;Karfreitag;KF;28.03.2016;Ostermontag;OM;01.05.2016;Tag der Arbeit;TA;05.05.2016;Christi Himmelfahrt;CH;16.05.2016;Pfingstmontag;PM;03.10.2016;Tag der Deutschen Einheit;DA;25.12.2016;1. Weihnachtstag;1W;26.12.2016;2. Weihnachtstag;2W;01.01.2017;Neujahr;NJ;14.04.2017;Karfreitag;KF;17.04.2017;Ostermontag;OM;01.05.2017;Tag der Arbeit;TA;25.05.2017;Christi Himmelfahrt;CH;05.06.2017;Pfingstmontag;PM;03.10.2017;Tag der Deutschen Einheit;DA;31.10.2017;Reformationstag;RT;25.12.2017;1. Weihnachtstag;1W;26.12.2017;2. Weihnachtstag;2W'; ;WITH cte AS (SELECT SUB.value, TRY_CONVERT(datetime, SUB.value) AS Datum FROM STRING_SPLIT(@data, ';') AS SUB WHERE ISDATE(SUB.value) = 1) SELECT *, DATENAME(weekday, cte.Datum) FROM cte WHERE YEAR(cte.Datum) = 2016 AND DATENAME(weekday, cte.Datum) <> 'Sonntag'
Eine gute Performanz darf man hier aber nicht erwarten.
Olaf Helper
[ Blog] [ Xing] [ MVP]- Bearbeitet Olaf HelperMVP Dienstag, 27. Dezember 2016 18:00
- Als Antwort vorgeschlagen Dimitar DenkovMicrosoft contingent staff, Administrator Donnerstag, 29. Dezember 2016 14:17
- Als Antwort markiert Dimitar DenkovMicrosoft contingent staff, Administrator Freitag, 6. Januar 2017 11:07
-
TRY_CONVERT gibt es ab SQL Server 2012, wenn Du trotzdem eine Fehlermeldung erhält, dann weil die Datenbank in einem älteren Kompatibilitätsmodus läuft; siehe Anzeigen oder Ändern des Kompatibilitätsgrads einer Datenbank
STRING_SPLIT gibt es erst ab 2016, deswegen mein Hinweis, kannst Du aber durch dieses Skript ersetzen: Convert Small CSV Value to Table
Olaf Helper
[ Blog] [ Xing] [ MVP] -
Danke, bekomme aber jetzt folgende Fehlermeldung :o)
Ungültiger Objektname 'STRING_SPLIT'.
Es ist wahrscheinlich sinnvoller, den Tabellendesign zu ändern! Das Problem ist, dass ich auch dann an vielen Stellen im Programm den Code ändern muss. Lässt sich leider doch nicht vermeiden!
Gruesse, NUNUI
- Bearbeitet Nunui Dienstag, 27. Dezember 2016 19:11
-
Hi,
die sinnvollste Variante ist sicherlich die Änderung des Datenbankdesigns. Und achte zukünftig darauf, dass Du nicht mehrere Werte als String zusammenfasst, wenn Du die einzelnen Elemente noch in irgendeiner Form weiterverarbeiten musst (zumindest, wenn Du das per SQL machen musst)
Zur Fehlermeldung an sich: Olaf schrieb doch, dass STRING_SPLIT erst ab SQL Server 2016 zur Verfügung steht. Da du SQL Server 2012 verwendest, kann also nichts anderes als eine Fehlermeldung kommen.
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET
http://www.asp-solutions.de/ - Consulting, Development
http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community
- Bearbeitet Stefan FalzModerator Dienstag, 27. Dezember 2016 21:50