AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Bekomme Inner Joins nicht hin

Bekomme Inner Joins nicht hin

Offene Frage von "p80286"
Ein Thema von Der schöne Günther · begonnen am 18. Dez 2018 · letzter Beitrag vom 21. Dez 2018
Antwort Antwort
Seite 4 von 6   « Erste     234 56   
Jumpy

Registriert seit: 9. Dez 2010
Ort: Mönchengladbach
1.733 Beiträge
 
Delphi 6 Enterprise
 
#31

AW: Bekomme Inner Joins nicht hin

  Alt 19. Dez 2018, 12:42
Wir arbeiten hier mit einer Software mit über 1000 Tabellen, alls großteils historisch gesteuert, das ist ja sowas ähnliches wie deine Revisionen.
Die Infos dazu stehen jeweils in der Tabelle selber, in unserem Fall eine Art GültigVON und GültigBis Datum für den Datensatz.

Der Vorteil ist, wie du selber schon gemerkt hast, das die Abfragen einfacher werden, wenn du wissen willst, was der gerade aktuell gültige Datensatz ist. Wenn du daher aktuelle Items mit aktuellen Foos joinen willst und sowohl für Items als auch Foos musst du die Revisionstabelle dazu joinen oder abfragen, wird es schnell unübersichtlich und evtl. auch langsam.

Allerdings ist deine Intention mit der Revisionstabelle natürlich auch sinnvoll und dafür gibt es bei uns ein ChangeLog/ChangeHistory Tabellen Konstrukt, dass zwar nicht optimal (gewachsene Struktur) ist, aber man kann sehen wer hat was wann geändert (leider nicht warum).
Ralph
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.851 Beiträge
 
Delphi 11 Alexandria
 
#32

AW: Bekomme Inner Joins nicht hin

  Alt 19. Dez 2018, 12:46
Grundsätzlich ist Normalsisierung (bzw. SnowFlaking) sinnvoll. Man kann ja auch einen (Join-)View erstellen.
Markus Kinzler
  Mit Zitat antworten Zitat
Benutzerbild von jfheins
jfheins

Registriert seit: 10. Jun 2004
Ort: Garching (TUM)
4.579 Beiträge
 
#33

AW: Bekomme Inner Joins nicht hin

  Alt 19. Dez 2018, 13:05
Um dir noch etwas Lesestoff zu geben: Du hast da eine SCD (Slowly Changing Dimension)
Es gibt verschiedene Ansätze, wenn du die Historie behalten möchtest nur Typ 2 oder 3.

Bei Typ 2 kannst du die nicht mehr gültigen Daten in eine eigene Tabelle auslagern, muss aber nicht. Wichtiger wäre, dass du immer ein "Gültig bis" Datum drin speicherst, wenn das NULL ist, ist diese Zeile gültig.
Wenn du den Primary Key nicht auf dieses Feld erweitern möchtest, würde ich es auf zwei Tabellen splitten - siehe Beitrag von mkinzer:
Du hast Items, von welchem (1 zu n) Revisionen bestehen.
Und so allgemein solltest du dir überlegen, nicht nur einen Kommentar zu speichern, sonder auch, was sich geändert hat
  Mit Zitat antworten Zitat
jobo

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

AW: Bekomme Inner Joins nicht hin

  Alt 19. Dez 2018, 13:24
Mein Senf:
Ich versteh die Trennung, die (eigene) innere Ordnung der Dinge, die man erhalten möchte.
Das ist auch legitim und m.E. ebenso legitim, an dieser stelle "Insider Wissen" einzusetzen und bereits eine Trennung vorzunehmen, wenn sie faktisch in der bevorstehenden Version noch nicht benötigt wird.
Normalisierung ist kein Selbstzweck, sondern hat primär einen ganz simplen und wichtigen Grund:
Konsistenz

Wenn man sein Datenmodell so konstruiert, dass Konstistenz (garantiert) gewahrt bleibt, hat man nichts verkehrt gemacht. Den Zusatzaufwand treibt man aber nicht aus Vergnügen, es sollte schon irgendwelche Gründe geben, die nicht nur einem selbst bekannt (und akzeptiert) sind.

Bei einer Historisierung oder Revisionen hier wäre es m.E. wichtig dafür zu sorgen, das ein Basiszugriff auf aktuell gültige Daten per Default erfolgt. Das würde hier heißen, mit Views zu arbeiten, die Altdaten automatisch ausblenden.
Ausnahme wäre ggF. wenn die Historie teil des Business Case ist und irgendwelche Spezialisten ständig mit verschiedenen Ständen arbeiten (müssen).


Gerade erst gesehen:
Ist das vielleicht nur eine Fake Frage, weil DSG hier
https://www.delphipraxis.net/199015-...ml#post1421208
nicht weiter kommt?
Gruß, Jo

Geändert von jobo (19. Dez 2018 um 13:27 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

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

AW: Bekomme Inner Joins nicht hin

  Alt 19. Dez 2018, 15:29
Es ist ziemlich aussichtslos, eine DB-Struktur auf eventuell denkbare, zukünftige Anforderungen hin zu entwerfen. Wir können auch nur das beurteilen, was du uns hier beschreibst - nicht das, was du eventuell in Zukunft vorhast.
Einspruch, nur wenn definitiv ausgeschlossen ist, daß es keine zwei oder mehr Revisionen zu einem Item gibt, dann könnte man über eine Tabelle nachdenken. Und wenn man eine 1:n Beziehung von vorneherein in Betracht zieht, ist man auf der sicheren Seite.
Ausnahmen die es nieee geben wird sind zum

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

Registriert seit: 20. Jan 2006
Ort: Lübbecke
10.934 Beiträge
 
Delphi 12 Athens
 
#36

AW: Bekomme Inner Joins nicht hin

  Alt 19. Dez 2018, 16:06
Einspruch, nur wenn definitiv ausgeschlossen ist, daß es keine zwei oder mehr Revisionen zu einem Item gibt, dann könnte man über eine Tabelle nachdenken.
Deswegen ja meine Frage. So wie ich das verstanden habe, wird zu jeder neuen Revision je ein Datensatz in Item und Item_Rev angelegt und mit Item.rev = Item_rev.ID verknüpft. Ohne zusätzliche Spezifikationen ist das definitiv eine 1:1 Beziehung und die kann problemlos in einer Tabelle zusammengefasst werden.

Was die sichere Seite betrifft, steht man dort sehr häufig auch nur auf dünnem Eis. Analog zu Premature Optimization fällt das auch sehr leicht in die Kategorie Over-Engineering oder wie man hier landläufig sagt: unnötig kompliziert.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
jobo

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

AW: Bekomme Inner Joins nicht hin

  Alt 19. Dez 2018, 16:36
apropos 1:1
wie sind die Beispieldaten zu verstehen, die Werte für REV>Id passen m.E. nicht, Tippfehler oder Verständnisfehler bei mir?

https://www.delphipraxis.net/1421232-post25.html
Gruß, Jo
  Mit Zitat antworten Zitat
Benutzerbild von joachimd
joachimd

Registriert seit: 17. Feb 2005
Ort: Weitingen
672 Beiträge
 
Delphi 10.4 Sydney
 
#38

AW: Bekomme Inner Joins nicht hin

  Alt 19. Dez 2018, 17:09
Ich würde ja ganz stumpf eine "Master" Tabelle (item) machen, in welcher die aktuellen Items drin stehen. Und zwar immer in der neuesten Revision - zur Not auch noch mit Kommentar, warum diese Revision nötig war, dem Benutzernamen und einem Zeitstempel.
Daneben eine "History" Tabelle (item_history), welche prinzipiell gleich aufgebaut ist.
Bei jeder Änderung in der Master Tabelle wird der alte Record in die History Tabelle übertragen und fertig.

Ein select auf die Master Tabelle liefert die aktuellen items.
Wenn die verschiedenen Revisionen gebraucht werden, kommt ein UNION mit der History Tabelle.
Joachim Dürr
Joachim Dürr Softwareengineering
http://www.jd-engineering.de

Geändert von joachimd (19. Dez 2018 um 17:09 Uhr) Grund: Typo
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.093 Beiträge
 
Delphi 10 Seattle Enterprise
 
#39

AW: Bekomme Inner Joins nicht hin

  Alt 19. Dez 2018, 17:10
apropos 1:1
wie sind die Beispieldaten zu verstehen, die Werte für REV>Id passen m.E. nicht, Tippfehler oder Verständnisfehler bei mir?

https://www.delphipraxis.net/1421232-post25.html
Sorry, Tippfehler von mir. Habe es korrigiert.
  Mit Zitat antworten Zitat
jobo

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

AW: Bekomme Inner Joins nicht hin

  Alt 20. Dez 2018, 08:34
Hier sind 3 Varianten ohne Anspruch auf Vollständigkeit usw:
Code:
-- nur max(id) wenn garantiert(!) ist, dass sie eindeutig, aufsteigend ist (faule Lösung)
-- geht "immer" (Syntax)
select a.*, r.*
  from item a
  join (select max(id) fkey from Item_Rev) b
    on a.rev = b.fkey
  join item_rev r
    on a.rev = r.id;
 

-- erst max(timestamp), darüber die zugehörige ID holen-Reihenfolge nun egal-  ("ordentliche" Lösung)
--   ordentlich halt*, Syntax geht auch immer
select a.*, r.*
  from item a
  join (select id
          from item_rev ri
          join (select max(changetimestamp) x from Item_Rev) rx
            on ri.changetimestamp = rx.x) b
    on a.rev = b.id
  join item_rev r
    on a.rev = r.id;
 
-- top n, logisch sauber, vermeidet Group ganz, trendy
--   bin mir nicht ganz sicher, aber es wäre eine typische MS Lösung, die relativ früh (als erste?) die TOP Funktion eingeführt hatten
--   ich würde mal sagen, eine gute Lösung, m.E. ohne Group sozusagen straight forward, aber syntaktisch nicht sehr kompatibel
--      (ersetze "top n" durch "limit n" o.ä. für andere Systeme)
select a.*, r.*
  from Item a
  join (select top 1 id from Item_Rev
         order by changetimestamp desc) b
    on a.rev = b.id
  join item_rev r
    on a.rev = r.id;

zu *
Alles ist relativ. Diese Lösung vermeidet das vielleicht etwas theoretische ID Problem (aufsteigend=chronologische ID= höchste Revision).
Aber was ist, wenn changetimestamp sich später (per Trigger) ändert, weil z.B. rein Rechtschreibfehler korrigiert wurde?


Die anfangs von Dir gefundene SQLite Variante hat mich mehr als überrascht und stark an das mySQL Desaster erinnert.
Ich war bis gerade der Meinung, mySQL seien die Einzigen, die sowas gefährliches "anbieten". Deren Group By Syntax war angetreten, ~ohne weiteres~ eine richtige Antwort zu liefern, es kommt dort aber meist Schrott raus, wenn man sich nicht an die Spielregeln hält. SQLite ist dann wohl Nr. 2 in dieser Heldenliste.
Ein Zitat aus deren Hilfe
Zitat:
Side note: Bare columns in an aggregate queries. ...
... and so in many cases the value for "b" is undefined...
Das Ergebnis ist also undefiniert!!! Dein (richtiges) Ergebnis wäre nach dieser Beschreibung also Zufall?
Es geht noch weiter in der Hilfe. Dort wird beschrieben, dass nur bei min und max etwas besonderes gemacht wird, was dann tatsächlich Dein Ergebnis erklärt. Eine sehr bequeme "Abkürzung" für den Entwickler von etwas SQL Text, aber tatsächlich weit weg vom Standard. Ich find besonders den ersten Teil gefährlich. Würde ich mich nicht dran gewöhnen. Vielleicht hast Du selbst diese Doku gelesen und warst der Meinung, so gehört sich das ..

Und wo ich dabei bin. was das Thema "kompatibel" angeht:
Es gibt die verschiendenen ANSI SQL Versionen von 86 bis 2016. Daran hält sich leider niemand vollständig (Was m.E. schlimmer klingt, als es ist, da man bei sowas offenbar schon die wichtigsten Dinge angeht)
Den Wunsch nach Kompatibilität versteh ich gut, aber es ist wie bei verschiedenen Pascal Dialekten, eben nicht alles kompatibel.
SQLite ist m.E. ein Exot, weil es ganz klar anders positioniert ist, als MSSQL oder andere große. Auf der Ebene am ehesten vergleichbar mit dem embedded Part von Firebird, aber eben nur mit dem. Ebenso exotisch der lockere Umgang mit Typen, low concurrency Ansatz, ..
MSSQL ist da gefühlt eher Standard, aber fett und reich genug, eigene Features vor den Standard zu stellen. Das gilt ähnlich für die anderen Kommerzanbieter. Gewollt sind am ehesten die open source Systeme bemüht, Standards einzuhalten, hier fehlen dann leider oft die Ressourcen. Postgres legt allerdings sehr großen Wert auf die ANSI-SQL Normen und kriegt das auch ganz gut hin.
In der Praxis geschieht es häufig, dass man sich für eine Syntax entlang der Doku des verwendeten Systems entscheidet und dabei nicht Standard gemäß formuliert, obwohl die DB es verstehen würde. Die Mohrrübe ist dabei oft auch eine kleine Extraportion Komfort oder Funktionalität. "Alte Hasen" haben da den kleinen Vorteil, dass sie aus Gewohnheit "gut abgehangenes" SQL verwenden. (Was nicht immer wirklich ein Vorteil sein muss, weil sie die Mohrrübe gar nicht sehen).

Zum "Problem"
Für Group By gibt es eine Faustregel, mit der man gut fährt:
Alle nicht aggregierten Felder der Select Liste müssen im Group By genannt werden.
Gruß, Jo

Geändert von jobo (20. Dez 2018 um 08:37 Uhr)
  Mit Zitat antworten Zitat
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 +1. Es ist jetzt 19:10 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