Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi SQL abfrgae First 3 (https://www.delphipraxis.net/189742-sql-abfrgae-first-3-a.html)

MatthiasK 15. Jul 2016 10:03

Datenbank: Firebird • Version: 2.5 • Zugriff über: Zeos

SQL abfrgae First 3
 
Hallo,

ich sitz grad an nem Problem, wo ich mir ein wenig das Hirn zermartere.

ich habe eine Tabelle:

UserID, Zeit1, Zeit2, MinBetween, First3

MinBetween gibt die Minuten zwischen den zwei Zeiten an. First3 ist nur ein Integerfeld.

für jeden User gibts so im Durchschnitt 6-20 Datensätze ca. Ich will für jeden User die 3 Datensätze mit dem größten Wert von MinBetween.
bisher hab ich folgendes per sql versucht:
Code:
select first 3 * from tdaten2
erwartungsgemäß kommt da zwar 3 datensätze, aber leider Müll. Wie kann ich das machen, das für jede UserId die 3 größten werte von MinBetween durch ne 1 im Feld First3 gekennzeichnet werden?

Danke für Anregungen.

Neutral General 15. Jul 2016 10:13

AW: SQL abfrgae First 3
 
Also in einem normalen SELECT wirds glaube ich echt knifflig aber es gibt ja Execute-Blöcke:
Code:
EXECUTE BLOCK
RETURNS (user_id int, zeit1 timestamp, zeit2 timestamp, minbetween int, first3 int)
As
BEGIN
    FOR
        SELECT DISTINCT
            tabelle.user_id
        FROM tabelle
        INTO :user_id
    DO
    BEGIN
        FOR
            SELECT FIRST 3
                tabelle.zeit1,
                tabelle.zeit2,
                tabelle.minbetween,
                tabelle.first3
            FROM tabelle
            WHERE tabelle.user_id = :user_id
            ORDER BY tabelle.minbetween DESC
            INTO :zeit1, :zeit2, :minbetween, :first3
        DO
        BEGIN
            SUSPEND;
        END
    END
END
EDIT: Mein Code gibt jetzt nur die entsprechenden Datensätze zurück. Statt dem Suspend in der Schleife kannst du natürlich auch die 3 Datensätze Updaten und in first3 eine 1 schreiben.
EDIT2: Wobei das Feld First3 schon so aussieht als sollte es gar nicht existieren. Sobald du einen neuen Datensatz einfügst musst du ja alle first3-Felder aktualisieren, weil sich ja was geändert haben könnte.
Bist du sicher dass du dieses Feld brauchst? Auch das Feld minbetween ist so gesehen nicht notwendig weil sich minbetween wie du schon sagtest aus zeit1 und zeit2 ergibt.

MatthiasK 15. Jul 2016 10:49

AW: SQL abfrgae First 3
 
Zitat:

Zitat von Neutral General (Beitrag 1342716)
Also in einem normalen SELECT wirds glaube ich echt knifflig aber es gibt ja Execute-Blöcke:

EDIT: Mein Code gibt jetzt nur die entsprechenden Datensätze zurück. Statt dem Suspend in der Schleife kannst du natürlich auch die 3 Datensätze Updaten und in first3 eine 1 schreiben.
EDIT2: Wobei das Feld First3 schon so aussieht als sollte es gar nicht existieren. Sobald du einen neuen Datensatz einfügst musst du ja alle first3-Felder aktualisieren, weil sich ja was geändert haben könnte.
Bist du sicher dass du dieses Feld brauchst? Auch das Feld minbetween ist so gesehen nicht notwendig weil sich minbetween wie du schon sagtest aus zeit1 und zeit2 ergibt.

Die minbetween hab ich mir in die DB reingemacht, weil ich das dann auf einem Report mit ausgebe.
Das First3 ist als formatierungshilfe geplant auf dem Report. Kann ja dann per Expr. den Datensatz markieren.

Dein Block muss ich erstmal verstehen. Im Programmcode hätte ich ja per For-Schleife für jede ID ein select gemacht mit dem first 3 und dann auf das Ergebnis ein UPDATE. Aber das sollte auch eleganter per SQL in einem Statement funktionieren.

Mfg Matthias

Neutral General 15. Jul 2016 10:57

AW: SQL abfrgae First 3
 
Aber du kannst diese Sachen genauso im Report ausgeben ohne zusätzliche Felder:
Code:
SELECT
  datediff(MINUTE, tabelle.zeit1, tabelle.zeit2)
FROM tabelle
Und auch First3 lässt sich so ermitteln, wenn auch etwas aufwändiger.
Das First3-Feld schreit nur so nach Inkonsistenz.

MatthiasK 15. Jul 2016 11:06

AW: SQL abfrgae First 3
 
In Theorie und Praxis stimme ich dir da voll und ganz zu im Bezug auf die Inkonsistenz.
Aber in diesem Fall brauch ich mir da keine Sorgen machen. Die DB erhält keine Daten. Die wird vorher von einem Steuerungsrechner kopiert.

Der einzigste, der die Datenmenge verunstaltet, bin in diesem Moment ich mit meinem Programm.

Im Quickreport ne SQL Abfrage in nem Detail Band? Das ist mir neu. Wie geht das denn???

Neutral General 15. Jul 2016 12:02

AW: SQL abfrgae First 3
 
Zitat:

Zitat von MatthiasK (Beitrag 1342726)
Im Quickreport ne SQL Abfrage in nem Detail Band? Das ist mir neu. Wie geht das denn???

Naja du übergibst doch dem Report eine Datenmenge (Eine Query wahrscheinlich). Und in der Query selektierst du halt statt tabelle.minbetween einfach datediff(MINUTE, tabelle.zeit1, tabelle.zeit2) as minbetween

MatthiasK 20. Jul 2016 10:15

AW: SQL abfrgae First 3
 
Also,

übers WE hab ich viel versucht und bin noch häufiger gescheitert.

Zu dem execute block: den bekomm ich im sql manager nicht zum laufen.

habs jetzt mal in delphi nachgebastelt. läuft fehlerfrei, jedoch wirds in der tabelle nicht geschrieben.
ich seh auch grad nicht den grund dafür. habs ma step by step geprüft. läuft sauber durch, auch in der richtigen anzahl. (hab ma bei einem user nur 2 datensätze gemacht, damit ich nicht 3 sätze für den user als result fürs select hab.)

aber irgendwo ist der wurm drin. wenn ich dann im sql manager ein refresh auf die tabelle mach, ham alle felder noch den wert 0.

ich weiss, meine lösung ist nicht schön. ich brauch bloß langsam was, was funktioniert.

Delphi-Quellcode:
 
for i := 0 to Listbox1.Items.Count - 1 do
  begin
    with zquery do
    begin
      sql.clear;
      sql.Add('select first 3 Itemindex,Pausenbegin,Pausenende,Minutpause, gross from tdaten2 where Itemindex = :ii');
      ParamByName('ii').AsInteger := i ;
      open;
      first;
      for a := 0 to zquery.RecordCount - 1 do
      begin
        edit;
        zquery.FieldByName('gross').AsInteger := 44;
        post;
        zquery.Next;
      end;
    end;
  end;

Neutral General 20. Jul 2016 10:21

AW: SQL abfrgae First 3
 
Du musst in der Query auch den Primärschlüssel der Tabelle die du aktualisieren willst mitselektieren, sonst funktioniert das Edit/Post nicht.
PS: Für Firebird würde ich auf jeden Fall IBExpert (statt SQL-Manager) empfehlen.

p80286 20. Jul 2016 10:35

AW: SQL abfrgae First 3
 
Delphi-Quellcode:
 
    with zquery do
    begin
      sql.clear;
      sql.Add('select first 3 Itemindex,Pausenbegin,Pausenende,Minutpause, gross from tdaten2 where Itemindex = :ii');
.....
warum wird nicht einfach

Delphi-Quellcode:
 
    with zquery do
    begin
      sql.Text:='select first 3 Itemindex,Pausenbegin,Pausenende,Minutpause, gross from tdaten2 where Itemindex = :ii';
genutzt?
(über das
Delphi-Quellcode:
With
verliere ich mal kein Wort.

Gruß
K-H

MatthiasK 20. Jul 2016 11:11

AW: SQL abfrgae First 3
 
habs entsprechend geändert. geht trotzdem nicht. läuft immernoch fehlerfrei, aber wird nicht aktuallisiert...

ibexpert hatte ich mal. ich komm aber an keine version fürn privaten gebrauch ran.

aber fürs bloß mal reinschaun reicht auch der sql manager.


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:27 Uhr.
Seite 1 von 2  1 2      

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