# Datenbank Abfrage



## Bluedaishi (3. Feb 2020)

Guten Morgen.....
Ich habe eine Tabelle mit den Spalten SQN_Start und SQN_Stop

ich möchte alle Werte zwischen SQN_Start und SQN_Stop ausgeben aber das klappt irgendwie nicht .

Select * from testdb Where SQN_Start=1020 and SQN_Stop=90027

ich bekomme keine Werte ausgegeben 
hat jemand eine Idee was ich dort falsch mache 

vielen Dank für eure Hilfe


----------



## LimDul (3. Feb 2020)

Damit gibst du genau die Zeilen aus, wo die Spalte SQN_Start exakt den Wert 1020 und die Spalte SQN_Stop exakt den Wert 90027 hat. Da schein es keine zu geben. Was heißt für dich denn "zwischen". Welche Werte sollen zwischen 1020 und 90027 liegen? Also welcher Spalte.


----------



## Bluedaishi (3. Feb 2020)

Dazwischen können 10 ,15 , 50 oder mehr Datensätze liegen die ich gerne ausgeben will . Das heist ich brauche die ID die hinterlegt ist und noch eine weiter Spalte stake_ges


----------



## Bluedaishi (3. Feb 2020)

Die Tabelle sieht folgender Maßen aus

ID , SQN_Start , SQN_Stop , Stake_ges , Dateiname , Datei 
12 ,    300.        ,      750.      ,   62,80.      ,  d.csv        ,  blob 
12 ,    751.        ,      980.      ,   120,80.    ,  d1.csv.     , blob
12,     981         ,     1230.     ,    320,70.   , d2. Csv.    , blob

Mit select * from testDb where Id=12 and SQN_Start=300 and SQN_Stop=1230

dachte ich ich bekomme dadurch alle Datensätze


----------



## kneitzel (3. Feb 2020)

Dann musst Du genau definieren, welche Datensätze du haben willst. So wie ich Dich jetzt verstanden habe, willst Du haben:
SQN_START >= 300 AND SQL_Stop <= 1230

Es ist also extrem wichtig, dass Du selbst sauber formulierst, was Du willst. Wie schon gesagt wurde: Es existiert kein Datensatz bei dem SQL_Start gleich 300 und SQL_Stop gleich 1230 ist.


----------



## Bluedaishi (3. Feb 2020)

So wie auf dem Foto zusehen möchte ich die Daten zwischen den beiden SQN_Start und SQN_Stop haben


----------



## Meniskusschaden (3. Feb 2020)

Bluedaishi hat gesagt.:


> So wie auf dem Foto zusehen möchte ich die Daten zwischen den beiden SQN_Start und SQN_Stop haben


Es fehlt immer noch die Definition, was du mit "zwischen" meinst. Du willst offenbar abfragen, welche Zeilen innerhalb eines gegebenen Intervalls liegen. Die Zeilen selbst repräsentieren aber keine Punkte, sondern ebenfalls Intervalle. Es sind also Überlappungen möglich. Liegt beispielsweise das Intervall [500, 1500] nach deiner Definition "zwischen" dem Intervall [300, 1230]? Das musst du mal sauber beschreiben und ggfs. die möglichen Fälle unterscheiden.


----------



## krgewb (3. Feb 2020)

@Bluedaishi Was ist denn das für eine Spalte links von ID?


----------



## krgewb (3. Feb 2020)

@Meniskusschaden So wie ich es verstanden habe, will er z.B. diese Daten:


----------



## Bluedaishi (3. Feb 2020)

Genau aber diese bekomme ich nicht es kommt immer ein leeres ResultSet


----------



## kneitzel (3. Feb 2020)

Hast du denn dann mal ausprobiert, was ich in #5 geschrieben habe?


----------



## mrBrown (3. Feb 2020)

Ehrlich gesagt verwirrt mich das Bild nur mehr, als das es hilft.


Die Zeilen sind weder nach SQN_START noch nach SQN_STOP sortiert, sondern nach irgendwas anderem?

Und dann sollen alle Zeilen ab einem bestimmten SQN_START bis zu einem bestimmten SQN_STOP gesucht werden?


----------



## LimDul (3. Feb 2020)

Das wichtigste für das Verständnis ist - die beiden Spalten haben für die Datenbank *nichts* mit einander zu tun. Die eine könnte auch Alter heißen und die andere Gehalt. Das die eine Start und die andere Stop heißt und die anscheinend ein Intervall angeben, ist für die Datenbank vollkommen egal - wenn man das als Intervall interpretieren möchte, muss man das im SQL Query auch enstprechend formulieren.


----------



## Bluedaishi (3. Feb 2020)

Ja das ist ja mein Problem das ich nicht weiß wie


----------



## LimDul (3. Feb 2020)

Dann schreib mal die Zeilen ab und erkläre uns warum du welche Zeilen in deinem Ergebnis haben willst.


----------



## Bluedaishi (3. Feb 2020)

Okay mache ich wenn ich heute Abend davor sitze


----------



## Bluedaishi (3. Feb 2020)

Wenn ich den Start Sqn auswähle und den End Sqn möchte ich alle Spalten innerhalb der sqn Werte ausgegeben haben


----------



## mrBrown (3. Feb 2020)

Das dürfte am ehesten dem entsprechen, was @JustNobody in #5 genannt hat


----------



## Bluedaishi (3. Feb 2020)

Ja das hat jetzt funktioniert 
Danke euch allen zumal meine Erklärungen nicht so  waren danke sxhön an alle


----------



## mihe7 (3. Feb 2020)

Bluedaishi hat gesagt.:


> Ja das hat jetzt funktioniert


Das würde mich jetzt mit Blick auf den Screenshot aus #6 aber stark wundern.


----------



## Bluedaishi (4. Feb 2020)

Guten Morgen an der Konsole hat es funktioniert das ich alle Einträge bekomme . In der Anwendung mit JavaFX fehlt mir immer der letzte


----------



## kneitzel (4. Feb 2020)

Also wenn eine Abfrage auf einer Datenbank auf der Konsole (Also ich nehme mal an, in einem Textbasierten Datenbankclient a.la. mysql, psql, ...) dann sollte genau die gleiche Abfrage auch in der Java Applikation das gleiche Ergebnis bringen. Du könntest also einfach einmal die Details zeigen:
a) Was führst Du auf der Kommandozeile aus?
b) Was ist der Code in Deinem Java Programm?

Und ich bin auch ernsthaft am Überlegen, was Du genau willst / erwartest. Beim angesprochenen Bildschirmfoto hast Du ja eine Start und eine End Zeile markiert. Die Zeile unter der Endzeile scheint die Bedingung aber auch zu erfüllen.

Wenn diese Start / End Werte ein Intervall beschreiben und Du alle Elemente haben willst, die in dem Intervall liegen, dann hast Du die entsprechende Abfrage.

Sind dies aber geordnete Datensätze und du willst alle Datensätze haben von dem Element an wo Start den bestimmten Wert und bis hin zu dem Datensatz, bei dem der End Wert einen bestimmten Wert hat, dann muss es anders gehen. Auf dem Bild in #6 scheint es noch eine fortlaufende Nummerierung zu geben. Diese wäre dann evtl. nutzbar. Der Name ist uns jetzt nicht bekannt, aber da wäre dann evtl. etwas denkbar wie:

```
SELECT 
    * 
FROM 
    sometable
WHERE
    LfdNr >= (SELECT LfdNr FROM sometable WHERE SQN_START = ?) AND
    LfdNr <= (SELECT LfdNr FROM sometable WHERE SQN_STOP = ?)
```
Wobei das evtl. nicht ganz ausreichend ist. Evtl. muss die ID noch stimmen und so.

Falls das in dem Bild täuschte und es keine laufende Nummer war (sondern evtl. nur eine Nummerierung der Ergebnisse bei der verwendeten GUI), dann kann man sich so eine Nummerierung evtl. selbst schaffen über eine Common Table Expression (CTE).


----------



## Bluedaishi (4. Feb 2020)

Das kann Ich leider erst heute Abend machen da ich dienstlich nach Hannover muss


----------



## krgewb (8. Feb 2020)

Also ist der Screenshot falsch?

Angenommen, das Query ist

```
SELECT * FROM testDb WHERE Id = 408400236 AND SQN_START >= 13955 AND SQN_Stop <= 10531
```

Auf dem Screenshot von Beitrag #6 sind 21 Zeilen zu sehen.
Keine davon würde gefunden werden. Es gibt zwar zwei Zeilen, bei denen SQN_STOP kleiner oder gleich 10531 ist, 
aber in den Zeilen ist der SQL_START-Wert nicht hoch genug.


----------



## abc66 (9. Feb 2020)

Ok betrachten wir mal das folgende Beispiel:

```
create table demo1(id integer PRIMARY KEY AUTOINCREMENT, f integer, t integer);

INSERT INTO demo1 (f,t) VALUES (0,1);
INSERT INTO demo1 (f,t) VALUES (3,5);
INSERT INTO demo1 (f,t) VALUES (10,13);
INSERT INTO demo1 (f,t) VALUES (21,22);
INSERT INTO demo1 (f,t) VALUES (4,6);
INSERT INTO demo1 (f,t) VALUES (9,14);
```

Jetzt hast du eine Tabelle demo1 mit 6 Zeilen, von denen sich zwei "Zeilen" (10,13 und 9,14) auf jeden Fall überschneiden.

Alle Zeiten, die sich nicht überschneiden, kannst du dann so

```
select * from demo1 where id not in (SELECT d1.id from demo1 as d1 inner join demo1 as d2 WHERE (d1.f < d2.f and d1.t > d2.t) or (d1.f > d2.f and d1.t < d2.t));
```
oder so

```
select * from demo1 as d1 where not EXISTS (SELECT id from demo1 as d2 where (d1.f < d2.f and d1.t > d2.t) or (d1.f > d2.f and d1.t < d2.t));
```
ermitteln. Ich denke das ist genau das was du suchst....


----------



## Meniskusschaden (9. Feb 2020)

abc66 hat gesagt.:


> Alle Zeiten, die sich nicht überschneiden, kannst du dann so ... oder so ... ermitteln.


Damit würden aber auch einige Zeilen ausgegeben, die sich eben doch überschneiden. Beispielsweise wenn mehrere Zeilen dasselbe Intervall haben.


abc66 hat gesagt.:


> Ich denke das ist genau das was du suchst....


Wenn das tatsächlich gewünschte Ergebnis nichts mit den Screenshots und auch nichts mit der verbalen Anforderungsbeschreibung zu tun hat, könnte es das wirklich sein. Wäre also durchaus möglich.


----------



## abc66 (9. Feb 2020)

Meniskusschaden hat gesagt.:


> Damit würden aber auch einige Zeilen ausgegeben, die sich eben doch überschneiden. Beispielsweise wenn mehrere Zeilen dasselbe Intervall haben.
> 
> Wenn das tatsächlich gewünschte Ergebnis nichts mit den Screenshots und auch nichts mit der verbalen Anforderungsbeschreibung zu tun hat, könnte es das wirklich sein. Wäre also durchaus möglich.


Naja, eine Überschneidung liegt auf jeden Fall dann vor, wenn die Startzeit 1 vor der Startzeit 2 liegt und die Endzeit 1 nach der Endzeit 2 liegt. Andernfalls muss er die Bedingung eben umformulieren. Ich denke das schafft er.


----------



## Meniskusschaden (9. Feb 2020)

abc66 hat gesagt.:


> Naja, eine Überschneidung liegt auf jeden Fall dann vor, wenn die Startzeit 1 vor der Startzeit 2 liegt und die Endzeit 1 nach der Endzeit 2 liegt.


Das ist eben nur eine kleine Teilmenge der möglichen Fälle für Überschneidungen. Und du hattest ja nicht geschrieben, deine Abfrage würde Überschneidungen finden (da könnte man die Ergebnisse noch als korrekt aber unvollständig ansehen), sondern überschneidungsfreie Zeilen (da ist das Ergebnis einfach falsch). Selbst wenn man Teilüberlappungen außen vor lässt, erkennt sie nicht mal Überschneidungen, die zum selben Zeitpunkt beginnen, aber zu unterschiedlichen Zeitpunkten enden.


----------



## abc66 (9. Feb 2020)

Meniskusschaden hat gesagt.:


> da ist das Ergebnis einfach falsch


Ist doch Humbug, ich kenne die genaue Anforderungsdefinition nicht und bin auch nicht verpflichtet diese ("imaginäre") einzuhalten. Mit nur etwas Transferleistung lässt sich die Menge der möglichen Fälle beliebig anpassen.

Sagen wir so, das Gebäude habe ich gebaut, die gewünschten Fenster muss er eben noch selber einsetzen...

Außerdem wusste ich gar nicht genau, ob er nach den Überschneidungen oder den Nicht-Überschneidungen sucht...


----------



## Meniskusschaden (9. Feb 2020)

abc66 hat gesagt.:


> Meniskusschaden hat gesagt.:
> 
> 
> > da ist das Ergebnis einfach falsch
> ...


Ich habe ja auch nicht behauptet, es sei bezüglich der ursprünglichen Anforderungsdefinition falsch, sondern lediglich bezüglich deiner eigenen Leistungsbeschreibung:


abc66 hat gesagt.:


> Alle Zeiten, die sich nicht überschneiden, kannst du dann so ...


Vielleicht war ja auch nicht deine Abfrage, sondern nur deine Beschreibung fehlerhaft.



abc66 hat gesagt.:


> Sagen wir so, das Gebäude habe ich gebaut, die gewünschten Fenster muss er eben noch selber einsetzen...


In dem Fall wäre eine etwas defensiver programmierte Abfrage vorteilhafter gewesen.


----------



## mihe7 (9. Feb 2020)

abc66 hat gesagt.:


> eine Überschneidung liegt auf jeden Fall dann vor, wenn die Startzeit 1 vor der Startzeit 2 liegt und die Endzeit 1 nach der Endzeit 2 liegt.


Zwei Intervalle (v1,b1) und (v2,b2) überschneiden sich in jedem Fall, wenn b1 > v2 und b2 > v1 gilt.


----------



## abc66 (9. Feb 2020)

Also eingentlich ist mir das relativ egal, weil ich über eine Sql-Abfrage niemals an so eine Fragestellung herangehen würde... Da code ich lieber etwas festes. 

Ok, in Prüfungen wird man natürlich genau zu dem Scheiß gezwungen... aber sonst?


----------



## LimDul (9. Feb 2020)

abc66 hat gesagt.:


> Also eingentlich ist mir das relativ egal, weil ich über eine Sql-Abfrage niemals an so eine Fragestellung herangehen würde... Da code ich lieber etwas festes.
> 
> Ok, in Prüfungen wird man natürlich genau zu dem Scheiß gezwungen... aber sonst?


Sonst Lagert man sowas bei großen Datenmengen an die Datenbank aus, weil es aus Performance (und Speicher) Gründen nicht sinnvoll ist, sowas im Code zu machen.


----------



## abc66 (9. Feb 2020)

LimDul hat gesagt.:


> Sonst Lagert man sowas bei großen Datenmengen an die Datenbank aus, weil es aus Performance (und Speicher) Gründen nicht sinnvoll ist, sowas im Code zu machen.


Hm bevor der von mir geschriebene Code langsam werden würde, müsste schon einiges passieren...


----------



## LimDul (9. Feb 2020)

Nun ganz simpel: Wenn wir von mehreren 100.000ten Objekten in der DB reden und JPA dazwischen ist viel sinnvoller die Datenbank die Filterung machen zu lassen als alle zu laden und dann in Java zu filtern. Der Code in Java ist performant, trotzdem muss ich nicht 100.000 Objekte erzeugen, wenn ich am Ende nur 10 brauche.


----------



## Bluedaishi (9. Feb 2020)

SELECT ID, SQN_START, SQN_STOP, STAKE_GES FROM FISKAL_DATEN WHERE ID='408400250' AND (SQN_START>'6943' OR SQN_START='6943')AND (SQN_STOP='9992' OR SQN_STOP<'9992' ) ORDER BY SQN_START ASC

so habe ich es bis jetzt probiert aber es haut nicht hin mit sqn_stop
mir fehlt dann immer der letzte Eintrag vom sqn_stop = 9992


----------



## kneitzel (9. Feb 2020)

Bluedaishi hat gesagt.:


> SELECT ID, SQN_START, SQN_STOP, STAKE_GES FROM FISKAL_DATEN WHERE ID='408400250' AND (SQN_START>'6943' OR SQN_START='6943')AND (SQN_STOP='9992' OR SQN_STOP<'9992' ) ORDER BY SQN_START ASC
> 
> so habe ich es bis jetzt probiert aber es haut nicht hin mit sqn_stop
> mir fehlt dann immer der letzte Eintrag vom sqn_stop = 9992


Also kannst Du einmal die Daten vernünftig posten - so dass diese lesbar sind. Was ist SQN_START bei dem Datensatz, der fehlen soll?

Und welche Datenbank nutzt Du? Da sollte doch eigentlich ein <= unterstützt werden, oder sollte es eine Datenbank geben, die das nicht kann?


----------

