Delphi-PRAXiS
Seite 2 von 2     12   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Datum aus voriger Zeile zum berechnen (https://www.delphipraxis.net/201703-datum-aus-voriger-zeile-zum-berechnen.html)

p80286 24. Aug 2019 11:40

AW: Datum aus voriger Zeile zum berechnen
 
(langfristig hilft das ungemein!)

Da ich nicht weiß, bzw. nachvollziehen kann ob der Subselect funktioniert, solltest Du sicherstellen daß
SQL-Code:
...
JulianDay(Qechtdat) -
(SELECT JulianDay(Qechtdat) As Integer
...
solche mißverständlichen Formulierungen nicht auftauchen.
Und dann
SQL-Code:
...
JulianDay(Qechtdat) -coalesce(
(SELECT JulianDay(Qechtdat) As PrevDate
...
,0)
From ......
und dann schauen wir mal weiter.

Gruß
K-H

concept2015 24. Aug 2019 16:50

AW: Datum aus voriger Zeile zum berechnen
 
Die ganze Abfrage mit Subselect und Ergebnis steht in #38
Subselect klappt.
Nur die erste Zeile ist logischerweise falsch, da kein Datum davor existiert.

In meinem Beipiel steht in der ersten Zeile eine 20 ???
wo nimmt er die her ?

Die erste Zeile muss zwingend eine 0 sein

Die Abfrage:
 
SELECT Qechtdat,wer,nummer
FROM Zwischen
where Jahr = "2019"
and nummer = "139"
order by Qechtdat

bringt die Rohdaten:
 
QEchtDat WER Nummer
2019-01-10 Demag 139
2019-01-19 Demag 139
2019-01-25 Demag 139
2019-02-01 Demag 139
2019-02-08 Demag 139
2019-02-13 Demag 139
2019-02-27 Demag 139
Ich brauche:
2019-01-10 //erster Besuch (keine vergangenen Tage)
//Tage = 0
//weil nicht mit Datum vorher berechenbar.

2019-01-19 //zweiter Besuch wieviel Tage sind vergangen
// seit erstem Besuch = 9
2019-01-25 //dritter Besuch wieviel Tage sind vergangen
// seit zweitem Besuch = 6
...

Ich muss praktisch den ersten Durchlauf ohne Berechnung
machen - alle weiteren mit Berechnung.

-coalesce((SELECT JulianDay(Qechtdat) As PrevDate
...
,0)
bringt einen Syntax-Fehler bei as

Wenn ich z.B. eine Zählvariable einbauen könnte, würde ich Sql erst ab dem zweiten Satz berechnen lassen.

p80286 24. Aug 2019 21:22

AW: Datum aus voriger Zeile zum berechnen
 
Oh entschuldige,da hab ich mich vertan

SQL-Code:
-coalesce(SELECT JulianDay(Qechtdat)...
,0) As PrevDate
Gruß
K-H

P.S.
Wenn der Subselect funktioniert sollte er null für den ersten Datensatz liefern das wird dann durch coalesce(subselect,0) zu 0, und das war doch was du wolltest?

concept2015 25. Aug 2019 07:47

AW: Datum aus voriger Zeile zum berechnen
 
Hallo :-D,
egal, wie ich den Befehl coalesce einbaue, Syntax Fehler.

Hier nochmal der Code, der bis auf die erste Zeile klappt
Code:
SELECT Qechtdat,wer,nummer,
JulianDay(Qechtdat) -
(SELECT JulianDay(Qechtdat) As Tage
FROM Zwischen t2
WHERE t2.nummer = t1.nummer AND
JulianDay (t2.Qechtdat) < JulianDay(t1.Qechtdat)
ORDER BY
JulianDay(t2.Qechtdat)
DESC LIMIT 1) AS Tage FROM Zwischen t1
where Jahr = "2019"
and nummer = "139"
Ich hab noch keine verständliche deutsche Erklärung für den Befehl "coalesce" gefunden, darum fische ich mit Deinem Tip im trüben.
Aber trotzdem vielen Dank für Deine Geduld.

HolgerX 25. Aug 2019 09:41

AW: Datum aus voriger Zeile zum berechnen
 
Hmm..

Zitat:

Zitat von concept2015 (Beitrag 1443076)
Ich hab noch keine verständliche deutsche Erklärung für den Befehl "coalesce" gefunden, darum fische ich mit Deinem Tip im trüben.
Aber trotzdem vielen Dank für Deine Geduld.

Google mit 'coalesce' gibt direkt als erstes:
https://docs.microsoft.com/de-de/sql...ql-server-2017

Die Beschreibung ist gleich mit der von MySQL (2. Link in EN), Oracle und SQLite:
https://www.w3schools.com/sql/func_mysql_coalesce.asp
https://docs.oracle.com/cd/B28359_01...htm#SQLRF00617
http://www.sqlitetutorial.net/sqlite...lite-coalesce/

Somit sollte diese Funktion in allen DB-Systemen vorhanden sein...

und somit sollte
-coalesce((SELECT JulianDay(Qechtdat) As PrevDate , 0)

entweder das letzte Datum, wenn vorhanden und somit nicht NULL, zurück liefern, ansonsten, wenn kein Datum vom SubSelect kommt (somit NULL) die '0'.

concept2015 25. Aug 2019 13:23

AW: Datum aus voriger Zeile zum berechnen
 
Der Code:
Code:
JulianDay(Qechtdat) - 
coalesce((SELECT JulianDay(Qechtdat) PrevDate , 0)
FROM Zwischen t2
Liefert im SQLiteExpertPro64 und in Delphi den Fehler:
near "Form":syntax error

Auch in einer Zeile geschrieben :(

p80286 25. Aug 2019 17:53

AW: Datum aus voriger Zeile zum berechnen
 
Zähl mal die Klammern!

Gruß
K-H

concept2015 25. Aug 2019 18:00

AW: Datum aus voriger Zeile zum berechnen
 
Die Abfrage mit coalesce:
Code:
SELECT Qechtdat,wer,nummer,
JulianDay(Qechtdat) - 
coalesce((SELECT JulianDay(Qechtdat) as Tage ,0)
FROM Zwischen t2
WHERE t2.nummer = t1.nummer AND
JulianDay (t2.Qechtdat) < JulianDay(t1.Qechtdat)
ORDER BY
JulianDay(t2.Qechtdat)
DESC LIMIT 1) AS Tage FROM Zwischen t1
where Jahr = "2019"
and nummer = "139"
Es kommt - der beschriebene Fehler

Die gleiche Abfrage ohne coalesce
Code:
SELECT Qechtdat,wer,nummer,
JulianDay(Qechtdat) - 
(SELECT JulianDay(Qechtdat) as Tage
FROM Zwischen t2
WHERE t2.nummer = t1.nummer AND
JulianDay (t2.Qechtdat) < JulianDay(t1.Qechtdat)
ORDER BY
JulianDay(t2.Qechtdat)
DESC LIMIT 1) AS Tage FROM Zwischen t1
where Jahr = "2019"
and nummer = "139"
Bis auf Zeile 1 läuft es.
Wo habe ich den Fehler ?

p80286 25. Aug 2019 18:10

AW: Datum aus voriger Zeile zum berechnen
 
SQL-Code:
SELECT Qechtdat,wer,nummer,
  JulianDay(Qechtdat) - 
  coalesce(SELECT JulianDay(Qechtdat)
         FROM Zwischen t2
         WHERE t2.nummer = t1.nummer
           AND JulianDay (t2.Qechtdat) < JulianDay(t1.Qechtdat)
         ORDER BY JulianDay(t2.Qechtdat) DESC LIMIT 1),0) AS Tage
FROM Zwischen t1
  where Jahr = "2019"
  and nummer = "139"
Gruß
K-H

concept2015 25. Aug 2019 18:32

AW: Datum aus voriger Zeile zum berechnen
 
1 zu 1 kopiert
:(
near "Select": syntax error
:pale:

HolgerX 25. Aug 2019 19:08

AW: Datum aus voriger Zeile zum berechnen
 
Zitat:

Zitat von concept2015 (Beitrag 1443162)
Die Abfrage mit coalesce:
Code:
SELECT Qechtdat,wer,nummer,
JulianDay(Qechtdat) - 
coalesce((SELECT JulianDay(Qechtdat) as Tage ,0)
FROM Zwischen t2
WHERE t2.nummer = t1.nummer AND
JulianDay (t2.Qechtdat) < JulianDay(t1.Qechtdat)
ORDER BY
JulianDay(t2.Qechtdat)
DESC LIMIT 1) AS Tage FROM Zwischen t1
where Jahr = "2019"
and nummer = "139"
Es kommt - der beschriebene Fehler

coalesce((SELECT JulianDay(Qechtdat) as Tage ,0)

Wie p80286 schon schrieb : Zähl die Klammern!
-> 3x Öffnen und nur 2x Schließen....

coalesce((SELECT JulianDay(Qechtdat) as Tage) ,0)

So müsste diese Zeile lauten.... ;)

concept2015 26. Aug 2019 06:04

AW: Datum aus voriger Zeile zum berechnen
 
In dem kleinen Ausschnitt betrachtet:

coalesce((SELECT JulianDay(Qechtdat) as Tage ,0)

stimmt es, was ihr sagt - aber der Blick auf die Ganze Abfrage zeigt, das die Klammern richtig sind.

Wenn ich coalesce( und ,0) entferne, läuft die
Abfrage, bis auf den Fehler in Zeile 1 der Ausgabe.

Schokohase 26. Aug 2019 06:38

AW: Datum aus voriger Zeile zum berechnen
 
Dann schauen wir uns die Abfrage in der Gänze an und arbeiten uns mal zum Kern weiter vor:
SQL-Code:
SELECT Qechtdat,wer,nummer,
JulianDay(Qechtdat) - 
coalesce((SELECT JulianDay(Qechtdat) as Tage ,0)
FROM Zwischen t2
WHERE t2.nummer = t1.nummer AND
JulianDay (t2.Qechtdat) < JulianDay(t1.Qechtdat)
ORDER BY
JulianDay(t2.Qechtdat)
DESC LIMIT 1) AS Tage FROM Zwischen t1
where Jahr = "2019"
and nummer = "139"
Jetzt nehmen wir (ausgehend von den Klammern) alles das, was zum
SQL-Code:
coalesce(...)
gehört:
SQL-Code:
coalesce((SELECT JulianDay(Qechtdat) as Tage ,0)
FROM Zwischen t2
WHERE t2.nummer = t1.nummer AND
JulianDay (t2.Qechtdat) < JulianDay(t1.Qechtdat)
ORDER BY
JulianDay(t2.Qechtdat)
DESC LIMIT 1)
und nun betrachten wir mal das Innere von
SQL-Code:
coalesce(...)
SQL-Code:
(SELECT JulianDay(Qechtdat) as Tage ,0)
FROM Zwischen t2
WHERE t2.nummer = t1.nummer AND
JulianDay (t2.Qechtdat) < JulianDay(t1.Qechtdat)
ORDER BY
JulianDay(t2.Qechtdat)
DESC LIMIT 1
Dieses ergibt einfach keinen Sinn und wird darum auch zurecht als fehlerhaft zurückgewiesen.

Ein einfaches Klammern zählen hilft hier nicht.

Billa 26. Aug 2019 06:39

AW: Datum aus voriger Zeile zum berechnen
 
Hallo,

ich bin hier gerade reingestolpert habe mir das SELECT-Statement nur sehr oberflächlich angeschaut. Könnte etwas mehr Klarheit erreicht werden, wenn allen selektierten Feldern der Qualifier der jeweiligen Abfrage vorangestellt würde? Ich sehe z.B. nicht auf einen Blick, welches "QechtDat" in Zeile 4 gewünscht ist: das aus T1 oder das aus T2? Also "T1.QechtDat" oder "T2.QechtDat"...

In solchen Fällen hilft es mir, wenn ich "von aussen nach innen" arbeite. In diesem Fall also statt der inneren Abfrage mit coalesce erstmal eine Konstante eintragen und schauen, ob die Ergebnisse den Voraussetzungen entsprechen. Erst wenn das ok ist, erweitere ich die Abfrage.

ähhh.... Schokohase war schneller.

Schokohase 26. Aug 2019 06:55

AW: Datum aus voriger Zeile zum berechnen
 
So und zur Auflösung gibt es jetzt auch ein wirklich funktionierendes Statement, was tatsächlich auch die Werte liefert, die gewünscht sind:
SQL-Code:
SELECT
  Qechtdat,
  wer,
  nummer,
  JulianDay(Qechtdat) - COALESCE(
    ( 
      SELECT
        JulianDay(Qechtdat) As Tage
      FROM
        Zwischen t2
      WHERE
        t2.nummer = t1.nummer
      AND
        JulianDay (t2.Qechtdat) < JulianDay(t1.Qechtdat)
      ORDER BY
        JulianDay(t2.Qechtdat) DESC
      LIMIT
        1
    ),
    JulianDay(Qechtdat)
  ) AS Tage
FROM
  Zwischen t1
WHERE
  Jahr = "2019"
AND
  nummer = "139";
und hier auch noch der Beweis

concept2015 26. Aug 2019 07:09

AW: Datum aus voriger Zeile zum berechnen
 
Danke für die Mühe - aber der Fehler im Ergebnis (Zeile 1) ist
noch da !
In der ersten Zeile kann kein Datum vorher stehen - muss also null
sein -

Die Grunddaten sind:
QEchtDat WER Nummer
2019-01-10 Demag 139
2019-01-19 Demag 139
2019-01-25 Demag 139
2019-02-01 Demag 139
2019-02-08 Demag 139
2019-02-13 Demag 139

Es handelt sich hier um Kundenbesuche mit der Frage, wieviele Tage zwischen den Besuchen liegen.
Logischerweise kann in Zeile 1 keine Berechnung erfolgen, da es sich um den ersten Besuch handelt.

Das gesuchte Ergebnis müsste so aossehen:
QEchtDat WER Nummer Tage
2019-01-10 Demag 139 0
2019-01-19 Demag 139 9
2019-01-25 Demag 139 6
....

Schokohase 26. Aug 2019 07:12

AW: Datum aus voriger Zeile zum berechnen
 
Klickst du auf der Beweis

Ich sehe da als Ergebnis
Code:
QEchtDat       WER     Nummer Tage
2019-01-10      Demag   139     0
2019-01-19      Demag   139     9
2019-01-25      Demag   139     6
2019-02-01      Demag   139     7
2019-02-08      Demag   139     7

concept2015 26. Aug 2019 07:28

AW: Datum aus voriger Zeile zum berechnen
 
:-D:-D:-D

Bei mir in SqLiteexpert:

QEchtDat WER Nummer Tage
2019-01-10 Demag 139 20
2019-01-19 Demag 139 9
2019-01-25 Demag 139 6
2019-02-01 Demag 139 7
2019-02-08 Demag 139 7
2019-02-13 Demag 139 5

:oops:

So weit waren wir doch schon ohne COALESCE(

Und auf DER BEWEIS kommt kein Ergebnis ?
You need to build the schema before you can run a query.

Schokohase 26. Aug 2019 07:40

AW: Datum aus voriger Zeile zum berechnen
 
Liste der Anhänge anzeigen (Anzahl: 2)
Screenshot sqlfiddle
Anhang 51583
Screenshot SQliteExpert
Anhang 51584
Ich kann dir anscheinend nicht helfen (ich frage mich allerdings auch wer es könnte)

jobo 26. Aug 2019 08:09

AW: Datum aus voriger Zeile zum berechnen
 
Zitat:

Zitat von concept2015 (Beitrag 1443244)
Und auf DER BEWEIS kommt kein Ergebnis ?
You need to build the schema before you can run a query.

sqlfiddle hinkt manchmal oder will einen anderen Browser..
einfach später noch mal probieren

"Build Your Schema" möchte nur, dass Du den Knopf drückst, um Tabellen anzulegen und Daten einzuspielen, also das Script auf der linken Seite (manuell) starten.
Auf der rechten kannst Du die Abfrage formulieren, ändern, starten.

Ist aber alles auch Wurscht, wenn es nicht klappt. Das ist ja nur ein Hilfsmittel, um online 100% das Gleiche zu machen und über das Gleiche zu reden.
Script kopieren und lokal ausführen muss zum gleichen Ergebnis führen, das ist der Punkt.

Jumpy 26. Aug 2019 08:18

AW: Datum aus voriger Zeile zum berechnen
 
Idee: In den Subselect muss auch die Einschränkung auf Jahr und Monat rein!

Die 20 in der ersten Zeile sind somit die Tage seit dem letzten Besuch im Vormonat und da z.B. Schokohase vermutlich in seinen Testdaten keinen Vormonat hat, kommt er da auf 0? Evtl. liefert der Subselect nach der Einschränkung Null statt 0, dann muss da ggf. noch sowas wie ein "Wenn Null dann 0" drum, in Oracle wäre das NVL, keine Ahnung wie bei FB der Befehl heißt.

jobo 26. Aug 2019 08:22

AW: Datum aus voriger Zeile zum berechnen
 
Also klar, andere Daten ergeben natürlich andere Ergebnisse. Dafür ist ja ein Testfall da, wie Schokohase ihn gemacht hat.

concept2015 26. Aug 2019 14:16

AW: Datum aus voriger Zeile zum berechnen
 
Der Tip von Ralph war goldrichtig.
Idee:
In den Subselect muss auch die Einschränkung auf Jahr und Monat rein!

Code:
SELECT
  Qechtdat,wer,nummer,
  JulianDay(Qechtdat) - COALESCE(
    (SELECT JulianDay(Qechtdat) As Tage
      FROM Zwischen t2
      WHERE t2.nummer = t1.nummer
      AND JulianDay (t2.Qechtdat) < JulianDay(t1.Qechtdat)
      AND t2.Jahr = "2019" -- <---- !
      AND nummer = "139"  -- <---- !
      ORDER BY
      JulianDay(t2.Qechtdat) DESC
      LIMIT 1),JulianDay(Qechtdat)) AS Tage
   FROM Zwischen t1
   WHERE Jahr = "2019"
   AND nummer = "139"
bringt:

QEchtDat WER Nummer Tage
2019-01-10 Demag 139 0
2019-01-19 Demag 139 9
2019-01-25 Demag 139 6
2019-02-01 Demag 139 7
2019-02-08 Demag 139 7
2019-02-13 Demag 139 5
2019-02-27 Demag 139 14

Mit COALESCE( .... ohne ,0)

DANKE Ralph :-D:-D:-D
Und auch DANKE an alle anderen, die sich über mein Problem den Kopf zerbrochen haben.8-)

p80286 26. Aug 2019 21:16

AW: Datum aus voriger Zeile zum berechnen
 
Zitat:

Zitat von concept2015 (Beitrag 1442978)
Die ganze Abfrage mit Subselect und Ergebnis steht in #38
Subselect klappt.

Pardon, das konnte ich mir nicht verkneifen.
oder https://de.wikipedia.org/wiki/Vertra...lle_ist_besser!

Gruß
K-H


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:58 Uhr.
Seite 2 von 2     12   

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