AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Abfrage in Firebird DB über 6 Tabellen

Abfrage in Firebird DB über 6 Tabellen

Ein Thema von daniel775 · begonnen am 9. Sep 2017 · letzter Beitrag vom 12. Sep 2017
Antwort Antwort
Seite 1 von 2  1 2   
daniel775

Registriert seit: 27. Nov 2010
46 Beiträge
 
#1

Abfrage in Firebird DB über 6 Tabellen

  Alt 9. Sep 2017, 13:22
Datenbank: Firebird • Version: 2.5.2.26540 • Zugriff über: SQL-Manager lite
Hallo,


ich verzweifel gerade an einer Abfrage bzw. an dem Konstrukt der Tabellen in Firebird.

Also die Tabellen müssen folgende Anforderungen erfüllen:
- Ein Artikel muss mehreren Lieferanten zuzuordnen sein.
- Jeder Artikel kann eine fremde Artikel-Nr eines Lieferanten haben.
- Jeder Artikel hat unterschiedliche Einkaufspreise von jeden Lieferanten mit unterschiedlichen Zeiträumen.


Auszug aus dem Aufbau der Tabellen:
(Siehe Anhang)


SQL-Query
Code:

SELECT k.Firmenname, k.KREDITORNR, k1.Datum, pr.LISTENPREIS_NETTO, pr.EKPREIS_NETTO
FROM
KREDITOREN as k,
KREDITOR_PREISE as pr,
REL_KREDITOR_ARTIKEL as r,
REL_KRED_ART_PREISE as rp
JOIN KREDITOREN on k.ID = r.KREDITOR_ID
JOIN REL_KREDITOR_ARTIKEL on r.id = rp.KREDITOR_ART_ID
JOIN REL_KRED_ART_PREISE on rp.KREDITOR_PREISE_ID = pr.id
JOIN (SELECT k.id, MAX(pr.SDATETIME) as Datum
FROM
KREDITOREN as k,
REL_KREDITOR_ARTIKEL as r,
KREDITOR_PREISE as pr
JOIN KREDITOREN on k.ID = r.KREDITOR_ID
JOIN REL_KREDITOR_ARTIKEL on r.KREDITOR_ART_ID = pr.KREDITOR_ART_ID
GROUP BY k.id
) k1
on k1.id = k.id
GROUP BY k.Firmenname, k.KREDITORNR, k1.Datum, pr.LISTENPREIS_NETTO, pr.EKPREIS_NETTO
ORDER BY k1.Datum;

Ergebnis meiner Abfrage ist, das ich 4 Zeilen Ergebnis bekomme, obwohl ich nur 2 Erwarte mit
jeweils eine Zeile und den aktuellen Preisen der beiden Lieferanten.

Wobei das Datum von dem Datensatz der eigentlich nicht im Ergebnis sein soll, das Datum vom Datensatz übernommen hat, das durch "JOIN (SELECT k.id, MAX(pr.SDATETIME) as Datum" als größten Datensatz selektiert wurde.

Die Tabelle "Kreditor_Preise" hat 4 Zeilen. Jeder Lieferant der beiden hat zwei Zeilen. Wobei jede Zeile ein unterschiedliches Datum hat. Also das Ergebnis soll sein 2 Zeilen, 2 Lieferanten, 2 aktuelle Preise. Also mit dem ältesten Datum.

Also zurück zu meinen eigentlichen Frage. Wie erreiche ich bei einer gruppierten Abfrage das nur der Datensatz mit dem ältesten Datum in der Ergebnismenge ist?
Wie muss ich die Tabellen umdesignen um die o.g. anfoderungen zu erfüllen?


Beispiel:
ID Datum Listenpreis Einkaufspreis
1 05.05.2017 699,00 492,70
2 13.08.2017 599,00 392,70
3 25.05.2017 749,00 654,99
4 05.09.2017 799,00 699,99


Über einen Lösungsansatz über den ich auch nachgedacht habe wäre folgender:

D Datum Listenpreis Einkaufspreis Aktiv
1 05.05.2017 699,00 492,70 0
2 13.08.2017 599,00 392,70 1
3 25.05.2017 749,00 654,99 0
4 05.09.2017 799,00 699,99 1

Halt mit einen zusätzlichen Datenfeld "Aktiv"


Danke für das Lesen, hoffe auf zahlreiche-/hilfreiche Antworten
Miniaturansicht angehängter Grafiken
tabellen-beziehungen.jpg  

Geändert von daniel775 ( 9. Sep 2017 um 13:38 Uhr)
  Mit Zitat antworten Zitat
Neumann

Registriert seit: 6. Feb 2006
Ort: Moers
505 Beiträge
 
Delphi 10.4 Sydney
 
#2

AW: Abfrage in Firebird DB über 6 Tabellen

  Alt 10. Sep 2017, 10:02
Das ganze sieht für mich - der weder alle Tabellenstrukturen kennt noch genügend Beispieldaten hat - erstmal etwas undurchsichtig aus.

Man könnte es mit 2 Ansätzen (auch kombinierbar) vereinfachen:

1. Mit Views arbeiten, die vereinfachte Zwischentabellen für die Abfrage liefern.

2. Mit einer Stored Procedure arbeiten.

Habe auch schon das Problem gehabt, dass zu viele Joins in einer Abfrage oft ein Ergebnis liefern, das man nicht erwartet oder haben will.
Ralf
Gruß vom Niederrhein
  Mit Zitat antworten Zitat
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
7.991 Beiträge
 
Delphi XE4 Professional
 
#3

AW: Abfrage in Firebird DB über 6 Tabellen

  Alt 10. Sep 2017, 10:25
Hallo,
bei LaTex heißt es in solchen Fällen immer "Minimal-Beispiel",
also poste eine GDB an, die eine minimale Anzahl an Datensätzen enthält,
aber bei deiner Query falsche Ergebnisse liefert.

Dann noch mal:
Ist
Soll
Heiko
  Mit Zitat antworten Zitat
daniel775

Registriert seit: 27. Nov 2010
46 Beiträge
 
#4

AW: Abfrage in Firebird DB über 6 Tabellen

  Alt 10. Sep 2017, 12:50
OK,

ich habe einen Auszug aus den Tabellen gebaut. Die DB befindet sich im Anhang. Das SQL Script zum extrahieren wollte leider nicht richtig funktionieren. Hänge es aber trotzdem mal an.


SQL Statement für die Abfrage:

SELECT k.Firmenname, k.KREDITORNR, k1.Datum, pr.LISTENPREIS_NETTO, pr.EKPREIS_NETTO
FROM
KREDITOREN as k,
KREDITOR_PREISE as pr,
REL_KREDITOR_ARTIKEL as r,
REL_KRED_ART_PREISE as rp
JOIN KREDITOREN on k.ID = r.KREDITOR_ID
JOIN REL_KREDITOR_ARTIKEL on r.id = rp.KREDITOR_ART_ID
JOIN Kreditor_Preise on rp.KREDITOR_PREISE_ID = pr.id
JOIN (SELECT k.id, MAX(pr.SDATETIME) as Datum
FROM
KREDITOREN as k,
REL_KREDITOR_ARTIKEL as r,
KREDITOR_PREISE as pr
JOIN KREDITOREN on k.ID = r.KREDITOR_ID
JOIN REL_KREDITOR_ARTIKEL on r.KREDITOR_ART_ID = pr.KREDITOR_ART_ID
GROUP BY k.id
) k1
on k1.id = k.id
GROUP BY k.Firmenname, k.KREDITORNR, k1.Datum, pr.LISTENPREIS_NETTO, pr.EKPREIS_NETTO
ORDER BY k1.Datum;

Komischerweise bekomme ich bekomme ich jetzt nur einen Lieferanten bei der Abfrage.
Angehängte Dateien
Dateityp: 7z TESTDB.7z (47,2 KB, 7x aufgerufen)
Dateityp: 7z TESTDB_SQL.7z (2,9 KB, 3x aufgerufen)
  Mit Zitat antworten Zitat
hstreicher

Registriert seit: 21. Nov 2009
217 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#5

AW: Abfrage in Firebird DB über 6 Tabellen

  Alt 10. Sep 2017, 13:21
Ich würde erst mal die Doppelten Tabellen rauswerfen und dann entweder SQL 89 oder SQL 92 Syntax verwenden und nicht beides gleichzeitig

mfg Hannes
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.658 Beiträge
 
Delphi 7 Personal
 
#6

AW: Abfrage in Firebird DB über 6 Tabellen

  Alt 10. Sep 2017, 15:27
versuch es mal hiermit:
SQL-Code:
SELECT K.irgendwas,KP.Sdatetime
FROM
  Kreditoren as k
    join Rel_Kreditor_Artikel KAr on k.ID=KAr.Kreditor_ID
    join Artikel A on A.ID=KAr.Art_ID
    join Kreditor_Artikel KA on KA.ID=KAr.Kreditor_Art_ID
    join Rel_Kred_Art_Preise KAPr on KAPr.Kreditor_Art_ID=KA.ID
    Join Kreditor_Preise KP on KAPr.Kreditor_Preise_ID=KP.ID
where 1=1
  and max(KP.sDatetime)
group by k.irgendwas
Gruß
K-H
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector
  Mit Zitat antworten Zitat
daniel775

Registriert seit: 27. Nov 2010
46 Beiträge
 
#7

AW: Abfrage in Firebird DB über 6 Tabellen

  Alt 10. Sep 2017, 19:23
Also irgendetwas stimmt an dem Query nicht. Wenn ich "and max(KP.sDatetime)" weglasse, dann bekomme ich zumindest ein Ergebnis. Sonst die Errormessage
"Invalid token.
Dynamic SQL Error.
SQL error code = -104.
Token unknown - line 11, column 1.
Group."
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.658 Beiträge
 
Delphi 7 Personal
 
#8

AW: Abfrage in Firebird DB über 6 Tabellen

  Alt 10. Sep 2017, 19:30
wenn Du
"Group by k.irgendwas" genutzt hast, dann kann das nicht funktionieren, das ist der Platzhalter für Daten, die du aus der Kreditoren-Tabelle abfragen willst.

Gruß
K-H
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector
  Mit Zitat antworten Zitat
daniel775

Registriert seit: 27. Nov 2010
46 Beiträge
 
#9

AW: Abfrage in Firebird DB über 6 Tabellen

  Alt 10. Sep 2017, 19:36
Irgendwie hab ich befürchtet das die Antwort kommt. Nein, hab ich natürlich nicht 1:1 genutzt!
sondern:

SELECT k.Firmenname, k.KREDITORNR, KP.datum, KP.LISTENPREIS_NETTO, KP.EKPREIS_NETTO
FROM
Kreditoren as k
join Rel_Kreditor_Artikel KAr on k.ID = KAr.Kreditor_ID
join Artikel A on A.ID = KAr.Art_ID
join Kreditor_Artikel KA on KA.ID = KAr.Kreditor_Art_ID
join Rel_Kred_Art_Preise KAPr on KAPr.Kreditor_Art_ID = KA.ID
join Kreditor_Preise KP on KAPr.Kreditor_Preise_ID = KP.ID
where 1=1
and max(KP.SDATETIME) as datum
group by k.FIRMENNAME, k.KREDITORNR, KP.LISTENPREIS_NETTO, KP.EKPREIS_NETTO;


oder


SELECT k.Firmenname, k.KREDITORNR, KP.SDATETIME, KP.LISTENPREIS_NETTO, KP.EKPREIS_NETTO
FROM
Kreditoren as k
join Rel_Kreditor_Artikel KAr on k.ID = KAr.Kreditor_ID
join Artikel A on A.ID = KAr.Art_ID
join Kreditor_Artikel KA on KA.ID = KAr.Kreditor_Art_ID
join Rel_Kred_Art_Preise KAPr on KAPr.Kreditor_Art_ID = KA.ID
join Kreditor_Preise KP on KAPr.Kreditor_Preise_ID = KP.ID
where 1=1
and max(KP.SDATETIME)
group by k.FIRMENNAME, k.KREDITORNR, KP.LISTENPREIS_NETTO, KP.EKPREIS_NETTO;


oder

SELECT k.Firmenname, k.KREDITORNR, KP.sdatetime, KP.LISTENPREIS_NETTO, KP.EKPREIS_NETTO
FROM
Kreditoren as k
join Rel_Kreditor_Artikel KAr on k.ID = KAr.Kreditor_ID
join Artikel A on A.ID = KAr.Art_ID
join Kreditor_Artikel KA on KA.ID = KAr.Kreditor_Art_ID
join Rel_Kred_Art_Preise KAPr on KAPr.Kreditor_Art_ID = KA.ID
join Kreditor_Preise KP on KAPr.Kreditor_Preise_ID = KP.ID
where 1=1
group by k.FIRMENNAME, k.KREDITORNR, KP.sdatetime, KP.LISTENPREIS_NETTO, KP.EKPREIS_NETTO;


wobei ich beim letzten ein Ergebnis habe. Aber eben ohne " and max(KP.sDatetime) "
  Mit Zitat antworten Zitat
TBx
(Moderator)

Registriert seit: 13. Jul 2005
Ort: Stadthagen
1.791 Beiträge
 
Delphi 10.2 Tokyo Enterprise
 
#10

AW: Abfrage in Firebird DB über 6 Tabellen

  Alt 10. Sep 2017, 19:50
SQL-Code:
where 1=1
  and max(KP.SDATETIME) as datum
sollte da mal korrigiert werden, die erste Zeile enthält eine überflüssige Bedingung, da immer erfüllt und die zweite Zeile enthält nur einen Ausdruck, keine Bedingung.
Gruß Thomas
- Moderator Delphi-Praxis -
- Admin Delphi-Treff
- Embarcadero MVP
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2   

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +2. Es ist jetzt 23:28 Uhr.
Powered by vBulletin® Copyright ©2000 - 2021, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2021 by Daniel R. Wolf