Fragensteller
Feldinhalt bei Werten von - bis ermitteln

Allgemeine Diskussion
-
Hallo zusammen,
ich habe ein Sachverhalt was mir gerade etwas Probleme macht. Vlt. hat der eine oder andere ein Tipp für mich.
Ich muss aus einem Feld Daten lesen. Die Daten in der einen Spalte sind wie folgt hinterlegt:
Feld: PLZ
Datensatz1: 70100-75399
Datensatz2: 75400-76999
Datensatz3: 77000-89199, 90,92
Ich soll als Beispiel bei der Suche der PLZ 70150 den Datensatz 1 finden. Bei der Suche 90 oder 77100 soll der Datensatz 3 gefunden werden.
- Typ geändert Dimitar DenkovMicrosoft contingent staff, Administrator Freitag, 31. März 2017 12:08 Warten auf Rückmeldung
Alle Antworten
-
Hi,
trenne die Werte in zwei Spalten (nspw. MinValue, MaxValue) oder (was ich für besser halten würde, da es teils ja auch mehr als zwei Werte geben kann) erstell dir eine separate Tabelle für die Werte.
[PLZBereiche] ID ElterndatensatzId MinWert MaxWert
In "ElterndatensatzId" kommt der Primärschlüsselwert des eigentlichen Datensatzes. In MinWert und MaxWert kommen dann bspw. 70100 und 75399, 77000 und 89199, 90 und 90, 92 und 92, usw.
Dann kannst Du die Datensätze so ermitteln:
SELECT ... FROM Tabelle WHERE ID IN ( SELECT ElterndatensatzId FROM PLZBereiche WHERE @Wert BETWEEN MinWert AND MaxWert )
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 -
Hi,
dann geht es nicht. Zumindest nicht per SQL. Man könnte natürlich auf sehr aufwändigem und zeitraubendem Weg versuchen, den Quatsch anderweitig zu parsen, über Hilfstabellen usw. zu arbeiten aber ehrlich gesagt macht das wenig bis keinen Sinn und falls da mehr als nur ein paar hundert Datensätze vorkommen, wird das auch nichts, was man der Abfrageperformance her haben will.
Ich würde daher, wenn es gar nicht anders geht, eine bspw. nächtlich laufende Routine schreiben, die genau das oben gesagt macht, also die vorliegenden Daten parst und daraus eine Struktur baut, wie die, die ich oben gezeigt hatte. Diese Tabelle kann auch in einer anderen Datenbank liegen, wenn es sein muss.
Und sag demjenigen, der diese "Struktur" (die keine ist) verbrochen und die Anforderung, sowas zu filtern, gestellt hat, dass er bitte die Finger von Datenbanken lassen soll.
(Und Nein, das meine ich nicht böse, auch wenn es wahrscheinlich so klingt. Es bringt nur nichts, wenn jemand ohne Ahnung sowas kaputtes plant und dann Anforderungen stellt, die in dieser Struktur völlig abwegig sind).
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 Donnerstag, 16. März 2017 06:35
-
Hi Poli,
bei solch nicht normalisierter Datenbankstruktur, empfiehlt es sich, eine StoreProcedure auf Basis einer SQL CLR dll zu erstellen und dann im Programm wie eine Stored Procedure zu nutzen.--
Viele Grüsse
Peter Fleischer (ehem. MVP)
Meine Homepage mit Tipps und Tricks -
Hallo wie wäre es hiermit?
create FUNCTION [dbo].[sf_chk_Bereich]
(
@Bereich varchar (100),
@Wert int
)
returns bit
as
begin
DECLARE
@idx1 int,
@Part varchar (100),
@idx2 int,
@von int,
@bis int;
SET @idx1 = charindex (',', @Bereich);
while (@idx1 > 0)
BEGIN
SET @idx1 = charindex (',', @Bereich);
SET @Part = ltrim (rtrim (substring (@Bereich, 1, @idx1 - 1)));
SET @idx2 = charindex ('-', @Part);
if (@idx2 > 0)
BEGIN
set @von = convert (int, ltrim (rtrim (substring (@Part, 1, @idx2 -1))));
set @bis = convert (int, ltrim (rtrim (substring (@Part, @idx2 + 1, 100))));
END
else
BEGIN
set @von = convert (int, ltrim (rtrim (@Part)));
set @bis = @von;
END
if (@Wert between @von and @bis)
return 1;
SET @Bereich = ltrim (substring (@Bereich, @idx1 + 1, 100));
SET @idx1 = charindex (',', @Bereich);
END
return 0;
end
GO
SELECT PLZ from Tabelle where [dbo].[sf_chk_Bereich] (PLZ, @Wert) = 1;
-
Hallo Willi Spies,
Erstmal vielen Dank für den Denkansatz, den Du mit der Skalarwertfunktion gegeben hast. Ich habe jedoch bemerkt, dass die Funktion 0 zurückgibt, wenn die Zeichenfolge nur aus einem Intervall besteht, wie z.B. '70100-75399' oder wenn man nach dem letzten Wert (nach dem letzten Komma) sucht, z.B.
SELECT [dbo].[sf_chk_Bereich]('70100-75399,91,93',93)
Deine Funktion kann angepasst werden, indem anfangs SET @idx = 1 hinzugefügt wird, damit auch bei einem Bereich wie '70100-75399' die Schleife durchlaufen wird. Darüber hinaus wird die Funktion nach dem Wert, der sich nach dem letzten Komma befindet, suchen, wenn folgende Zeile am Ende der while-Schleife entfernt wird (da Du den Wert am Anfang der Schleife zuweist):
SET @idx1 = CHARINDEX(',',@Bereich);
Zusammengefasst etwa:
SET @idx = 1; while (@idx1 > 0) BEGIN SET @idx1 = charindex (',', @Bereich); IF idx1 > 0 SET @Part = ltrim (rtrim (substring (@Bereich, 1, @idx1 - 1))); ELSE SET @Part = @Bereich --für den Fall eines Bereichs vom Typ '70100-70355' SET @idx2 = charindex ('-', @Part); --... SET @Bereich = ltrim (substring (@Bereich, @idx1 + 1, 100)); END
Gruß,
DimitarBitte haben Sie Verständnis dafür, dass im Rahmen dieses Forums, welches auf dem Community-Prinzip „IT-Pros helfen IT-Pros“ beruht, kein technischer Support geleistet werden kann oder sonst welche garantierten Maßnahmen seitens Microsoft zugesichert werden können.