AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken SELECT FIRST 1 im JOIN möglich ?
Thema durchsuchen
Ansicht
Themen-Optionen

SELECT FIRST 1 im JOIN möglich ?

Ein Thema von MyRealName · begonnen am 14. Sep 2017 · letzter Beitrag vom 14. Nov 2017
Antwort Antwort
Seite 2 von 2     12   
Benutzerbild von MyRealName
MyRealName

Registriert seit: 19. Okt 2003
Ort: Heilbronn
679 Beiträge
 
Delphi 10.4 Sydney
 
#11

AW: SELECT FIRST 1 im JOIN möglich ?

  Alt 9. Nov 2017, 22:46
Naja, was ich will ist von allen Produkten zu einem bestimmten Datum den Durchschnittspreis.
Weiss nicht warum, ob es an der Db liegt oder so aber neuerdings ist die abfrage mit dem SubSelect extrem langsam geworden. Die tabelle hat 750k Datensätze mit 1120 verschiedenen Produkten
  Mit Zitat antworten Zitat
jobo

Registriert seit: 29. Nov 2010
3.072 Beiträge
 
Delphi 2010 Enterprise
 
#12

AW: SELECT FIRST 1 im JOIN möglich ?

  Alt 12. Nov 2017, 00:37
Was Du in #5 gemacht hast, das Subselect aus der Select Clause in den Join verschieben geht in der Form nicht. Der Bezug zu IA fehlt da innen drin, man kann da drinnen nichts referenzieren, was draußen in der Nachbarmenge liegt.
Das geht nur beim Subselect in der Select Clause, wie Du es vorher hattest oder auch mit CTE, wie vorgeschlagen, aber da ist mir auf die Schnelle nichts zu eingefallen.
Die Subselects wie Du es gemacht hast, sind praktisch, aber nicht die schnellsten. Für jeden Satz der Hauptmenge wird das Subselect neu gemacht.
Wenn man das Subselect als separaten Join baut, läuft das eleganter. Man muss allerdings die Joinkriterien mit nach außen legen.
Und dass ein First dann keinen Sinn mehr ergibt, weil eine große Ergebnismenge erzeugt wird, ist dann auch klar.

Was ich bei Dir in #5 nicht verstehe, was die Aggregate im äußeren Select sollen. Mir ist allerdings auch nicht klar, wie die Tabelle ItemAct strukturiert ist und was es mit der qty auf sich hat.
Ich würde es so versuchen:

Code:
SELECT IA.ItemId, IA.Item, IA.Qty, CP1.CP Costo  
  FROM ItemAct IA join
      (select f.itemid, f.cp, f.fecha, f.LOCATION     -- Eintrag am nächstem zum Stichtag mit CP
         from cp_fecha f join
             (SELECT ItemId , LOCATION, max(fecha) as fechamax -- Eintrag am nächstem zum Stichtag
                FROM Cp_Fecha                                 -- cp fehlt noch
               WHERE Fecha <= :cp_param
               group by itemid, LOCATION) fm
           on f.itemid = fm.itemid
          and f.fecha = fm.fechamax
          and f.LOCATION = fm.LOCATION) CP1 
           on cp1.ItemID = IA.ItemID;
Ob die Location bei der Sache eine Rolle spielt oder nicht, musst Du selber wissen, wenn nicht dann raus.
Gruß, Jo
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#13

AW: SELECT FIRST 1 im JOIN möglich ?

  Alt 12. Nov 2017, 01:38
Was Du in #5 gemacht hast, das Subselect aus der Select Clause in den Join verschieben geht in der Form nicht. Der Bezug zu IA fehlt da innen drin, man kann da drinnen nichts referenzieren, was draußen in der Nachbarmenge liegt.
In einigen DBMS gibt es sowas wie einen LATERAL JOIN (in Postgre SQL nennt es sich so), wo man auch im JOIN (links vom ON) auf die Ergebnismenge der anderen Tabellen zugreifen kann.

https://heap.engineering/postgresqls...-type-lateral/
https://oracle-base.com/articles/12c...ly-joins-12cr1
$2B or not $2B

Geändert von himitsu (12. Nov 2017 um 01:56 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#14

AW: SELECT FIRST 1 im JOIN möglich ?

  Alt 12. Nov 2017, 09:58
Unter Umständen wäre es sinnvoll die Durschnittspreise täglich fortzuschreiben. Dann würde das Gehampel mit dem Datum entfallen.

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

Registriert seit: 29. Nov 2010
3.072 Beiträge
 
Delphi 2010 Enterprise
 
#15

AW: SELECT FIRST 1 im JOIN möglich ?

  Alt 12. Nov 2017, 11:58
Es ist sowieso fraglich, ob das so schneller ist.
Wenn das Mengenverhältnis 750K:1K ist, dann ist das ursprüngliche Subselect gar nicht so dramatisch. Bei wirksamer Indexierung, sind es halt 1000 gezielte Zugriff aus der 750K Menge.
Meine Variante macht riesige Aggregationen wahrscheinlich sogar Fulltablescan, die eigentlich nur einseitig über das Datum eingeschränkt sind.

Angenommen, man untersucht die Menge und stellt das größte Datumsloch fest, könnte man das sicher auch als berechnete Untergrenze (fecha-größteLücke) in das Statement einbauen.

Gemäß der Frage des TE ist mein Vorschlag erstmal eine ziemlich allgemeingültige Lösung per Join. Dürfte überall laufen.
Ggf. hilft die CTE Nummer doch, das wäre quasi eine Lateral Variante.
MyRealName soll mal ausprobieren, wie das läuft.

Jeden Tag einen Mittelwert einzutragen, macht die 750K sicher auch nicht schlanker, dann spart man sich die Aggregierung, aber braucht "etwas" mehr Platz für die Daten und Indizierung.
Gruß, Jo
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#16

AW: SELECT FIRST 1 im JOIN möglich ?

  Alt 12. Nov 2017, 17:23
Jeden Tag einen Mittelwert einzutragen, macht die 750K sicher auch nicht schlanker, dann spart man sich die Aggregierung, aber braucht "etwas" mehr Platz für die Daten und Indizierung.
Eben drum, meiner Meinung nach kommt es auf die Häufigkeit der Abfrage an. Läuft sie jeden oder jeden zweiten Tag sollte man den Platz spendieren, wird die Frage nur jeden Monat gestellt, darf sie auch etwas Zeit Kosten.

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

Registriert seit: 19. Okt 2003
Ort: Heilbronn
679 Beiträge
 
Delphi 10.4 Sydney
 
#17

AW: SELECT FIRST 1 im JOIN möglich ?

  Alt 14. Nov 2017, 14:42
Was Du in #5 gemacht hast, das Subselect aus der Select Clause in den Join verschieben geht in der Form nicht. Der Bezug zu IA fehlt da innen drin, man kann da drinnen nichts referenzieren, was draußen in der Nachbarmenge liegt.
Das geht nur beim Subselect in der Select Clause, wie Du es vorher hattest oder auch mit CTE, wie vorgeschlagen, aber da ist mir auf die Schnelle nichts zu eingefallen.
Die Subselects wie Du es gemacht hast, sind praktisch, aber nicht die schnellsten. Für jeden Satz der Hauptmenge wird das Subselect neu gemacht.
Wenn man das Subselect als separaten Join baut, läuft das eleganter. Man muss allerdings die Joinkriterien mit nach außen legen.
Und dass ein First dann keinen Sinn mehr ergibt, weil eine große Ergebnismenge erzeugt wird, ist dann auch klar.

Was ich bei Dir in #5 nicht verstehe, was die Aggregate im äußeren Select sollen. Mir ist allerdings auch nicht klar, wie die Tabelle ItemAct strukturiert ist und was es mit der qty auf sich hat.
Ich würde es so versuchen:

Code:
SELECT IA.ItemId, IA.Item, IA.Qty, CP1.CP Costo  
  FROM ItemAct IA join
      (select f.itemid, f.cp, f.fecha, f.LOCATION     -- Eintrag am nächstem zum Stichtag mit CP
         from cp_fecha f join
             (SELECT ItemId , LOCATION, max(fecha) as fechamax -- Eintrag am nächstem zum Stichtag
                FROM Cp_Fecha                                 -- cp fehlt noch
               WHERE Fecha <= :cp_param
               group by itemid, LOCATION) fm
           on f.itemid = fm.itemid
          and f.fecha = fm.fechamax
          and f.LOCATION = fm.LOCATION) CP1 
           on cp1.ItemID = IA.ItemID;
Ob die Location bei der Sache eine Rolle spielt oder nicht, musst Du selber wissen, wenn nicht dann raus.
Habe die query probiert, die braucht aber sehr lange.
Für die Bewegungen des Inventars nutzt unser Programm eine Tablle ItemAct (Item Accounting nehme ich mal an, der Name kam schon so als ich in die Firma gekommen bin).
Qty (Quantity) ist die Menge, die pro Datensatz bewegt wird. Da steht dann z.B. drin dass zur Datum (Fecha) X das Produkt (Item) A -5 Einheiten durch das Document Y den Inventar der Bodega (das ist sowas wie eine Lagerhalle) entzogen wurden (zum Bsp durch Verkauf).
Mache ich dann SUM(Qty) zu einem Stichtag, danns ehe ich, wieviele Einheiten ich da zur Verfügung habe und die Idee ist ja, den Durchschnittspreis (Costo promedio = CP) daneben zu schreiben.

Sorry wenn mir machmal die Worte auf deutsch nicht geläufig sind, aber in Deutschland habe ich fast nichts in Warenwirtschaften programmiert, alles was ich darüber weiss ist eigentlich in spanisch.
  Mit Zitat antworten Zitat
Benutzerbild von MyRealName
MyRealName

Registriert seit: 19. Okt 2003
Ort: Heilbronn
679 Beiträge
 
Delphi 10.4 Sydney
 
#18

AW: SELECT FIRST 1 im JOIN möglich ?

  Alt 14. Nov 2017, 14:45
Jeden Tag einen Mittelwert einzutragen, macht die 750K sicher auch nicht schlanker, dann spart man sich die Aggregierung, aber braucht "etwas" mehr Platz für die Daten und Indizierung.
Eben drum, meiner Meinung nach kommt es auf die Häufigkeit der Abfrage an. Läuft sie jeden oder jeden zweiten Tag sollte man den Platz spendieren, wird die Frage nur jeden Monat gestellt, darf sie auch etwas Zeit Kosten.

Gruß
K-H
Ich habe hier eine Kundentabelle eine Firma welche Airlines in Bogota das Essen für die Flüge zubereitet. Die kaufen produkte nur 2-4x pro Monat und manchmal ändert sich der Preis das ganze Jahr nicht, deswegen macht eine Tabelle wue CP_Fecha (CP_Durchschnittspreis, Fecha=Datum) sinn, da es
1. eine kleinere Tabelle ist als die Bewegungstablle (ItemAct), also weniger Felder und ich habe das gefühl, dass FB da schenller abfragt
2. halt doch sehr viel weniger Register drin stehen und es sich schneller sucht.
  Mit Zitat antworten Zitat
jobo

Registriert seit: 29. Nov 2010
3.072 Beiträge
 
Delphi 2010 Enterprise
 
#19

AW: SELECT FIRST 1 im JOIN möglich ?

  Alt 14. Nov 2017, 16:36
Habe die query probiert, die braucht aber sehr lange.
..
Sorry wenn mir machmal die Worte auf deutsch nicht geläufig sind, aber in Deutschland habe ich fast nichts in Warenwirtschaften programmiert, alles was ich darüber weiss ist eigentlich in spanisch.
Das habe ich befürchtet. Deine alte Abfrage wird immer langsamer, weil sie per inline subselect alle Werte einzeln nachschlägt. Das sind aber nur 1000 +x wenn ich das richtig verstanden habe und es läuft vermutlich über den pk index, also sozusagen Direktzugriff.
Meine Version mit klassischem Join baut die ursprüngliche "First 1" Menge erstmal über alle Daten auf, das sind 750 K, ein riesiges Aggregat.

Du hast noch nicht verraten, wie das indiziert ist, z.B. Index auf fetch? Wäre natürlich doof, wenn der nicht da ist, macht aber in Summe nicht so einen Unterschied.
Wie gesagt, die Join Variante kann man wahrscheinlich tunen, z.B. mit fetcha Untergrenze = Wunschdatum - größte Lücke.

Wenn Du noch die Index scripte der beiden Tabellen lieferst und das Mengengerüst bestätigst (cp_Fetch 750k*, itemAct 1k*), könnte man da noch mal genau hinschauen.

Das mit den Worten finde ich nicht wild, man kann ja fragen, wenn es unverständlich ist.

* passt irgendwie nicht zu "kleine Tabelle" aus Deinem letzten Beitrag
Gruß, Jo

Geändert von jobo (14. Nov 2017 um 16:38 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 2     12   


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 +1. Es ist jetzt 13:55 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