Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi SQL Abfrage (https://www.delphipraxis.net/26859-sql-abfrage.html)

motu 30. Jul 2004 11:56


SQL Abfrage
 
Hallo,

ich möchte gern in einer Datenbank nach einem Wert suchen lassen, ist
er vorhanden, soll der Datensatz als auch der dem Wert entsprechende
vorhergehende als der Nachfolger angezeigt werden. Wenn der Wert
nicht gefunden wird, sollen aber auch Vorgänger und Nachfolger
angezeigt werden.
Zur Verfügung hab ich MSSQL und DelphiADO

Zur Erklärung: Meine DB sieht etwas so aus:

ID Wert
1 10
2 20
3 30
4 50
5 40
6 60

Ich kann also nicht einfach sagen: "Suche Wert, nimm DS mit ID+/-1"
Ich muß quasi erstmal meine Daten sortieren, dann suchen und dann das
Umfeld ausgeben lassen. Nur wie?

Hansa 30. Jul 2004 12:11

Re: SQL Abfrage
 
Zitat:

Zitat von motu
...Ich kann also nicht einfach sagen: "Suche Wert, nimm DS mit ID+/-1"

Wieso nicht ?

SQL-Code:
SELECT * FROM BLA WHERE ID BETWEEN (:ID-1 AND ID+1);
Syntax ohne Gewähr. "Between" auch. :mrgreen:

motu 2. Aug 2004 07:04

Re: SQL Abfrage
 
Zitat:

Zitat von "Hansa
Wieso nicht ?

Na weil, die Steigung der Werte nicht mit der Steigung der ID zusammenhängt. Wenn neue Werte in die DB eingetragen werden, bekommen die 'ne neue ID egal ob die Ende ans Ende, an den Anfang oder ind die Mitte gehören. Hinzu kommt, das ich dann immer einen Wert finden muß, der aber nicht immer vorhanden ist.

Macht aber nichts, soweit war ich vor ein paar Wochen schon. Da find ich schon eine andere Lösung, so wie damals.

SirThornberry 2. Aug 2004 07:12

Re: SQL Abfrage
 
naja, deine sql abfrage müsste dann einfach alles abfragen und sortiert zurück geben
SQL-Code:
select * from YOURTABLE order by ID ASC
mit TQuery.First, TQuery.Next etc. kannst du dann die ergebnisse durchgehen und nach deinem wert suchen. Wenn du diesen gefunden hast kannst du mit TQuery.Next den nachfolgenden Wert ermitteln und mit TQuery.Prior den davor liegenden Wert. Ob TQuery in Zusammenhang mit Ado geht weiß i leider nicht aber da wirds mindestens ähnliche Wege geben.

motu 2. Aug 2004 07:20

Re: SQL Abfrage
 
Zitat:

Zitat von SirThornberry
mit TQuery.First, TQuery.Next etc. kannst du dann die ergebnisse durchgehen und nach deinem wert suchen.

das hört sich gut an. Leider ist es in meinem Fall auch möglich, das der Wert nich in der Datenbank ist. dann soll der Wert davor, als auch der Wert danach angezeigt werden. Kriegen wir das auch hin?

SirThornberry 2. Aug 2004 07:31

Re: SQL Abfrage
 
Das sollte man auch hinn bekommen. Wenn du die Abfrage durchgeführt hast (muss nichtmal sortiert sein) dann kannst du die ergebnisse ja einfach durchgehen und danach suchen.
Delphi-Quellcode:
var LDavor, LDahinter, LTreffer, LCount: Integer;
begin
  LDavor := -1;
  LDahinter := -1;
  LTreffer := -1;
  for LCount := 0 to GefundeneDatensaetze.count - 1 do
  begin
    if (LDavor = -1) or ((GefundeneDatensaetze[LCount].ID > LDavor) and (GefundeneDatensaetze[LCount].ID < GesuchteID)) then
       LDavor := GefundeneDatensaetze[LCount].ID;
    if (LDahinter = -1) or ((GefundeneDatensaetze[LCount].ID < LDahinter) and (GefundeneDatensaetze[LCount].ID > GesuchteID)) then
       LDahinter := GefundeneDatensaetze[LCount].ID;
    if GefundeneDatensaetze[LCount].ID = gesuchteID then LTreffer := gesuchteID;
  end;
end;
Das ganze ist nur PseudoCode der veranschaulichen soll wie das ganze funktioniert, kann also nicht eins zu eins abgetippt werden und soll somit auch nur als denkanstoß dienen (hoffe ich hab kein Denkfehler dabei)

motu 2. Aug 2004 07:33

Re: SQL Abfrage
 
Hmm. Ich glaube Du bist zu sehr auf die ID fixiert. Die ID hilft mir nichts, da sie in keinem Zusammenhang mit den Werten steht, es mir aber um die Werte geht.

SirThornberry 2. Aug 2004 07:35

Re: SQL Abfrage
 
Dann musst du eben ID durch den anderen Spaltenwert ersetzen, es geht ja nur um das funktionsprinzip, das letztendliche proggen musst du eh selbst.

motu 2. Aug 2004 07:37

Re: SQL Abfrage
 
Zitat:

Zitat von SirThornberry
Dann musst du eben ID durch den anderen Spaltenwert ersetzen, es geht ja nur um das funktionsprinzip, das letztendliche proggen musst du eh selbst.

Hmm. Hmm. Hmm.
Dann kann ich aber wiederrum nicht mit +1 und -1 arbeiten. Ich schau mir grad eh eine SQL basierte Lösung an, damit ich das ganze auch gleich für ASP verwenden kann.

Hansa 2. Aug 2004 07:55

Re: SQL Abfrage
 
Du mußt zuerst mal sagen, von welchem Kriterium es abhängt, was "davor" oder "dahinter" bedeutet. Wenn es sich nicht um die ID handelt, was dann ?
Zitat:

Leider ist es in meinem Fall auch möglich, das der Wert nich in der Datenbank ist.
Das hört sich so an, als würdest du nach was suchen, was es nicht gibt und wenn es was nicht gibt, dann nach etwas ähnlichem von nichts. Das ist aber nun mal alles. :mrgreen:

Ich will damit sagen, daß die Fragestellung so unpräzise ist, daß wohl niemand etwas damit anfangen kann. Wie es aussieht gilt das mittlerweile auch für die DB. 8)

motu 2. Aug 2004 08:05

Re: SQL Abfrage
 
Zitat:

Zitat von Hansa
Wenn es sich nicht um die ID handelt, was dann ?

Um Messwerte.

Zitat:

Zitat von Hansa
Das hört sich so an, als würdest du nach was suchen, was es nicht gibt und wenn es was nicht gibt, dann nach etwas ähnlichem von nichts. Das ist aber nun mal alles. :mrgreen:

Das ist so falsch. Ich suche zwar nach etwas, das es so direkt nicht gibt, weiß aber ganz genau, das es etwas kleineres und etwas größeres gibt. z.B. meine Werte sehen so aus:
20
30
Wenn ich nun 25 habe, ist der nicht in der DB aber davor und danach gibt es was.

Zitat:

Zitat von Hansa
Ich will damit sagen, daß die Fragestellung so unpräzise ist, daß wohl niemand etwas damit anfangen kann.

Hmm. Trotz langer Überlegung meinerseits war es doch schwierig es halbwegs verstänldich auszudrücken.

Zitat:

Zitat von Hansa
Wie es aussieht gilt das mittlerweile auch für die DB. 8)

Selig sind die geistig Armen.

Hansa 2. Aug 2004 08:11

Re: SQL Abfrage
 
Aha, deine Werte sind "Mess"werte. Wieso sagst du das nicht gleich ? 8)

Zitat:

Zitat von motu
Selig sind die geistig Armen.

Ich will nicht hoffen, daß du selig wirst, denn die Lösung steht schon längst in meinem ersten Beitrag zum Thema. :wall:

teebee 2. Aug 2004 10:27

Re: SQL Abfrage
 
Vielleicht funktioniert ja so etwas in der Art bei Dir: (konnte es nicht richtig ausprobieren, habe nur MySQL und das ist mit UNION und Sortierung überfordert und TOP muss mit LIMIT gemacht werden)
Code:
(SELECT TOP 1 * FROM Messwerte WHERE (Wert<x) ORDER BY Wert DESC) UNION
(SELECT * FROM Messwerte WHERE (Wert=x)) UNION
(SELECT TOP 1 * FROM Messwerte WHERE (Wert>x) ORDER BY Wert ASC);
x ist der gesuchte Messwert.

Gruß, teebee

motu 2. Aug 2004 10:30

Re: SQL Abfrage
 
Zitat:

Zitat von teebee
Code:
(SELECT TOP 1 * FROM Messwerte WHERE (Wert<x) ORDER BY Wert DESC) UNION
(SELECT * FROM Messwerte WHERE (Wert=x)) UNION
(SELECT TOP 1 * FROM Messwerte WHERE (Wert>x) ORDER BY Wert ASC);

Danke. Genau daran arbeite ich grad, dabei bekomm ich aber einen Spaltenfehler. Die ORDER BY Bedingung ist in meinen Augen obsolet, da die Ergebnissmenge von TOP/MAX/GREATEST ja eigentlich nur einen Wert enthalten kann.

Jelly 2. Aug 2004 10:51

Re: SQL Abfrage
 
Zitat:

Zitat von motu
Die ORDER BY Bedingung ist in meinen Augen obsolet, da die Ergebnissmenge von TOP/MAX/GREATEST ja eigentlich nur einen Wert enthalten kann.

Nein, ist sie nicht. Lässt du order by weg, wird nach deinem Primary Key ausgegeben, und top 1 liefert dir den Datensatz mit der kleinsten ID, und nicht den mit dem größten Messwert.

Gruß,
Tom

Robert_G 2. Aug 2004 10:53

Re: SQL Abfrage
 
Moin Motu :hi:

Ich muss sagen, ich habe irgendwie nicht ganz kapiert worum es dir geht. :gruebel:

Ist es so?
  • Wert
    1
    2
    3
    4
    5
    7
Code:
[b]Vorgäger Wert Nachfolger[/b]
  <null>    1           2
       1     2           3
       2     3           4
       3     4           5
       4     5      <null>
Das wäre würdest du so hinbekommen:
SQL-Code:
SELECT Ref.DeinFeld As Val
      ,Tab1.DeinFeld As Pred
      ,Tab2.DeinFeld As Succ
FROM  DeineTabelle Tab1
      ,DeineTabelle Tab2
      ,DeineTabelle Ref
WHERE Tab1.DeinFeld = Ref.DeinFeld - 1 And
       Tab2.DeinFeld = Ref.DeinFeld + 1

teebee 2. Aug 2004 10:57

Re: SQL Abfrage
 
Ich habs mit MySQL gemacht und da gibt es kein TOP, da muss man es mit ORDERBY und LIMIT 'emulieren', Du kannst Dir das ORDERBY also tatsächlich sparen. Ein Statement, das auf jeden Fall funktioniert (habe es jetzt direkt im MySQL-Client getestet und nicht in MySQL-Front, was offensichtlich mit geklammerten Statements nicht klarkommt) ist dieses hier:
Code:
(SELECT * FROM Messwerte WHERE (wert<x) ORDERBY wert DESC LIMIT 1) UNION
(SELECT * FROM Messwerte WHERE (wert=x)) UNION
(SELECT * FROM Messwerte WHERE (wert>x) ORDERBY wert LIMIT 1);
Gruß, teebee

Jelly 2. Aug 2004 10:59

Re: SQL Abfrage
 
Zitat:

Zitat von Robert_G
Ich muss sagen, ich habe irgendwie nicht ganz kapiert worum es dir geht. :gruebel:

Hallo Robert_G,

gesucht wird zu einem Messwert x dessen direkter kleinster und größter Nachbar.

Bsp: Messwerte = (4,5,7,8,9,10).

Mit x = 7 soll z.B. Folgendes ausgegeben werden: 5,7,8
x=6: 5,7

Gruß,
Tom

mschaefer 2. Aug 2004 11:02

Re: SQL Abfrage
 
Moin, moin,

Zwischenfragen:

Sind die Messwerte in einer zeitlichen Abfolge?
Oder suchst Du nur die Wertmäßige Abfolge.

Oder hast einen Wert µ um den du herum nur jeweils
einen Wert suchst um diesen neu zu interpolieren ?

Grüße // Martin

motu 2. Aug 2004 11:32

Re: SQL Abfrage
 
Zitat:

Zitat von mschaefer
Sind die Messwerte in einer zeitlichen Abfolge?
Oder suchst Du nur die Wertmäßige Abfolge.

Wertmäßig.

Zitat:

Zitat von mschaefer
Oder hast einen Wert µ um den du herum nur jeweils
einen Wert suchst um diesen neu zu interpolieren ?

ich suche die umliegenden, um diese einfach anzeigen zu lassen.

Inzwischen habe ich mein Ziel allein durch Anpassung des SQL-Statements erreicht. Mal sehen, was als nächstes kommt.

motu 3. Aug 2004 07:23

Re: SQL Abfrage
 
Also falls nochmal jemand wie ich hier her kommt, pack ich mal zwei Lösungen hier rein.

Die Erste gibt nur den Wert, sofern vorhanden, sowie den Vorgänger/Nachfolger aus.
Da das die ASP-Source ist, müßte "&input1&" durch eine Variable ersetzt werden.

SQL-Code:
SELECT Spalten, MAX(wert) FROM Tabellen WHERE wert < "&input1&"
UNION
SELECT Spalten FROM Tabellen WHERE wert = "&input1&"
UNION
SELECT Spalten, MIN(wert) FROM Tabellen WHERE wert > "&input1&" ORDER BY wert

Die Zweite gibt 5 Vorgänger/Nachfolger aus:

SQL-Code:
SELECT Spalten
FROM Tabellen
WHERE Wert IN (SELECT TOP 5 Wert FROM Tabelle WHERE Wert < "&input1&" ORDER BY Wert DESC)
UNION
SELECT Spalten
FROM Tabellen
WHERE Wert = "&input1&"
UNION
SELECT Spalten
FROM Tabellen
WHERE Wert IN (SELECT TOP 5 Wert FROM Tabelle WHERE Wert > "&input1&" ORDER BY Wert)
ORDER BY Wert


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:59 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz