Verknüpfungsfehler durch WHERE BEdingung

Werbung:
I

Komplett? Dann habe ich etwas übersehen, Table Create oder Daten sind mir nicht aufgefallen.

Die Online Plattform ist nur ein Beispiel, das ist Luxus. Du kannst Create Script, Insert Statements, Select Statements, falsche Ergebnisse, Fehlermeldungen alle einfach hier reinkopieren, als Text.

Doch, "SQL Server" ist eine gängige Bezeichnung / "Abkürzung" für Microsoft SQL Server. Er wird auf dieser Online Plattform sogar für viele verschiedene Versionen angeboten. Vermutlich ist er (der Hersteller spezifische Server) für die Probleme, die Du hast noch nicht mal entscheidenend. Weil Deine Probleme sehr grundlegender Natur sind und auf jedem Server gleichermaßen auftreten.
SQL Server 2017
hier habe ich das mal vereinfacht dargestellt. Ich sehe das Problem, weiß allerdings nach wie vor nicht, wie es zu beheben ist!
 
Super!
In dem ersten Abschnitt (Tabellenerzeugung) gibt es keine Foreign Key Constraints. Ich weiß nicht, ob das dem Original entspricht oder ein "Übertragunsfehler" ist.
Annahme anhand der Bezeichnung:
Alle "Nummer" Spalten beziehen sich auf "Aufträge.Nummer".
Dann ergibt sich bei Deinem Beispiel Select in der Where Condition ".. AND B.Nr = W.Item " die Frage:
Warum ist Nummer überall ein Fremdschlüssel (reine Annahme, aber wirkt plausibel) und warum sollte dann die Spalte ITEM in WARENBUCHUNG ebenfalls ein Fremdschlüssel zu Nummer sein oder in sonst irgendeiner sinnvollen Beziehung dazu stehen, die diese Filterung in der Where Condition rechtfertigt?
 
Super!
In dem ersten Abschnitt (Tabellenerzeugung) gibt es keine Foreign Key Constraints. Ich weiß nicht, ob das dem Original entspricht oder ein "Übertragunsfehler" ist.
Annahme anhand der Bezeichnung:
Alle "Nummer" Spalten beziehen sich auf "Aufträge.Nummer".
Dann ergibt sich bei Deinem Beispiel Select in der Where Condition ".. AND B.Nr = W.Item " die Frage:
Warum ist Nummer überall ein Fremdschlüssel (reine Annahme, aber wirkt plausibel) und warum sollte dann die Spalte ITEM in WARENBUCHUNG ebenfalls ein Fremdschlüssel zu Nummer sein oder in sonst irgendeiner sinnvollen Beziehung dazu stehen, die diese Filterung in der Where Condition rechtfertigt?
Ich habe noch nicht mit foreign keys gearbeitet und weiß auch nicht, inwieweit die benötigt werden.
Alle Nummer spalten bezihen sich auf aufträge.nummer. Das ist Korrekt.
Ich habe auch überlegt das so zu machen:

select A.Nummer,B.BspText,W.Item,W.Split
FROM Aufträge AS A
LEFT JOIN Warenbuchung AS W ON A.Nummer = W.Nummer
LEFT JOIN Beanstandungen AS B ON W.Item = B.Nr
--LEFT JOIN Warenbuchung ON Beanstandungen.Nr = Warenbuchung.Item
WHERE W.Nummer ='1'

und dann die Verbindung ohne den Nummern schlüssel zu machen.
Dann bekomme ich aber nach wie vor das problem, dass alle Einträge dupliziert werden, allerdings wird die 0 mit aufgenommen.
Vielleicht ist das zielführender?
Und ein dickes danke für deine Geduld und Hilfe!
 
Ich habe noch nicht mit foreign keys gearbeitet und weiß auch nicht, inwieweit die benötigt werden.
Mmh, also ich glaube schon, dass Du mit sowas gearbeitet hast, mglw. ohne es zu wissen. Du hast es lediglich implizit genutzt.
Die explizite Angabe von Foreign Keys ist ja nichts anderes als dem Server zu verraten, welche Spalte einer Tabelle sich auf eine andere Spalte in einer (anderen) Tabelle bezieht. Der Server weiß also was wie zusammengehört und kann die korrekte Wertebefüllung überwachen.

In Deinem Fall scheint es mir so zu sein, dass weder der Server noch Du so Recht wissen, welche Spalten zusammen gehören. Kannst Du im Original nachschauen, welche Foreign Key Constraints definiert sind?

Wenn es so wäre, wie ich hier vermute, dann gibt es -ähnlich zu Deiner Idee- keine duplizierten Einträge:
Code:
select a.nummer,w.item,w.split
  from aufträge as a 
  left join warenbuchung as w on a.nummer = w.nummer
  left join beanstandungen as b on a.nummer = b.nummer and b.nr = w.item  
 where a.nummer ='1' ;
 
Mmh, also ich glaube schon, dass Du mit sowas gearbeitet hast, mglw. ohne es zu wissen. Du hast es lediglich implizit genutzt.
Die explizite Angabe von Foreign Keys ist ja nichts anderes als dem Server zu verraten, welche Spalte einer Tabelle sich auf eine andere Spalte in einer (anderen) Tabelle bezieht. Der Server weiß also was wie zusammengehört und kann die korrekte Wertebefüllung überwachen.

In Deinem Fall scheint es mir so zu sein, dass weder der Server noch Du so Recht wissen, welche Spalten zusammen gehören. Kannst Du im Original nachschauen, welche Foreign Key Constraints definiert sind?

Wenn es so wäre, wie ich hier vermute, dann gibt es -ähnlich zu Deiner Idee- keine duplizierten Einträge:
Code:
select a.nummer,w.item,w.split
  from aufträge as a
  left join warenbuchung as w on a.nummer = w.nummer
  left join beanstandungen as b on a.nummer = b.nummer and b.nr = w.item 
 where a.nummer ='1' ;
So scheint es ja zu funktionieren. Danke für die Hilfe. Schlüssel habe ich aber tatsächlich noch nie definiert und nur über die Joins gearbeitet. Ich bin immer davon ausgegangen, dass die Nummer, da in allen tabellen vorhanden der Schlüssel ist.
 
So scheint es ja zu funktionieren. Danke für die Hilfe. Schlüssel habe ich aber tatsächlich noch nie definiert und nur über die Joins gearbeitet. Ich bin immer davon ausgegangen, dass die Nummer, da in allen tabellen vorhanden der Schlüssel ist.
Also das glaub ich nicht, idR definiert man vor allem Primär Schlüssel. Es ist denkbar, dass Du nur an "fertigen" Tabellen arbeitest, die jemand anders "entwirft", die vielleicht sogar von einer Persistenz Engine "entworfen". So oder so, es gibt diese Schlüssel, man nützt sie logisch sowieso. Und wie Dein Beispiel zeigt auch nicht unbedingt nur einen pro Abfrage.

Jede Spalte, die sich inhaltlich auf den Primärschlüssel einer Tabelle bezieht, ist ein Fremdschlüssel, logisch betrachtet.
Physisch, also im Datenmodell kann, ja soll man das unbedingt angeben! Das hätte nicht nur enorme funktionale Vorteile für die DB, sondern auch bspw. wenn man in einem Datenbankforum oder unter Kollegen die Tabellendefinitionen postet. Dann weiß jeder, was gemeint ist.

Ich bin immer davon ausgegangen, dass die Nummer, da in allen tabellen vorhanden der Schlüssel ist.
Ja, ist sie auch, vermutlich- Du hast es im Create Statement nicht definiert- man ahnt es nur durch den Spaltennamen.
Der Punkt ist, es ist offenbar nicht der einzige Schlüssel. Wenn man Tabellen joint, sollte man vollständige Kriterien verwenden.

Das solltest Du Dir dringend mal genauer anschauen und verstehen.
Ich hoffe, Du verstehst auch langsam, warum Screenshots nicht besonders hilfreich sind, zu einer Lösung zu kommen.
 
Ich habe noch nicht mit foreign keys gearbeitet und weiß auch nicht, inwieweit die benötigt werden.
Schau Dir noch mal mein Beispiel an, da sind sie definiert. Foreign keys und Primary Keys, erstere funktionieren nicht ohne letztere.
Das geht auch mit MS SQL und das sind wirklich grundlegende Funktionen einer DB.
Ich empfehle in jedem Fall ein Tutorial dazu.
 
Ich hoffe, Du verstehst auch langsam, warum Screenshots nicht besonders hilfreich sind, zu einer Lösung zu kommen.
Das verstehe ich, ich wusste bis vorher nur nicht, dass es eine Onlineseite gibt, bei der ich Beispieltabellen erstellen kann, somit waren die Screenshots gedanklich für mich der einzige logische Weg mein Problem darzustellen. Danke für die Info.
"fertigen" Tabellen arbeitest, die jemand anders "entwirft", die vielleicht sogar von einer Persistenz Engine "entworfen".
Ich erstelle keine Tabellen, sondern lese nur Daten aus, dementsprechend -wenn es sowas gibt- hat es jemand anders erstellt. Ich habe mir nur alle tabellen angeguckt bund geguckt wie ich die verknüpfen kann. Ist das definieren des Schlüssels denn notwendig? Es scheint ja auch ohne zu funktionieren.
Das hätte nicht nur enorme funktionale Vorteile für die DB
Inwiefern?
 
Das hätte nicht nur enorme funktionale Vorteile

DBFiddle und ähnliche Seiten sind toll, aber wie gesagt nur eine Luxusvariante davon, was ich Dir nahegelegt habe bzw. was in einem Programmierforum Standard ist:
Einfach die "Texte", also Code, den Du bei DBFiddle eingetragen hast, hier im Forum posten, das reicht. Bei Datenbankfragen beinhaltet der Code das Datenmodell, also Tabellen Definitionsskripte, Trigger-wenn vorhanden, Daten, also Insertskripte und die eigentlichen Abfragen.
Allein das Lesen der (vollständigen) Tabellendefinition hilft (den Helfern). Es würde bspw. alle Schlüsselfelder zeigen, ohne dass man ein einziges Wort darüber verlieren müsste.

Wenn Du selbst Dir Tabellen anguckst, um festzustellen, wie Du sie verknüpfen könntest, machst Du das scheinbar anhand der Spaltennamen. Das ist dann Glückssache, ob es klappt und ausreicht.
Wie gesagt, das Createskript der Tabelle enthält eigentlich diese Angaben explizit, wenn es ordentlich gemacht ist. Du musst dann nicht verstehen oder raten oder die Sprache kennen, in der die Spalte benannt wurde. Wenn Du gemäß Deines Jobs nur Abfragen bauen musst, kann es leider sein, dass du nicht mal das Recht hast, diese Infos über das Datenmodell in deiner IDE abzulesen. Und IDE können das natürlich darstellen, sofern es jemand definiert und freigegeben hat. (In diesem Fall sollte man diese Informationen allerdings auf anderem Weg zur Verfügung gestellt bekommen.)
Und nein, das Definieren von Schlüsseln oder Fremdschlüsseln ist nicht notwendig. Das ist ja das "Gefährliche", Bequeme, Blöde!
Ich kenne Systeme (käuflich), die diese Informationen extra nicht in der DB angeben, weil sie es geheim halten wollen. Sie wollen nicht von Dritten kopiert, gelesen, verstanden oder weiterverarbeitet werden.
Kann man so machen, hindert einen Neugierigen am Ende auch nicht, die Schlüsselfelder rauszufinden, hindert einen Böswilligen dann ebensowenig, Daten zu manipulieren.

Ich hab jetzt keine Lust eine Hausarbeit über Datenmodellierung und ihren Sinn zu schreiben.
Vielleicht mal so: Es gibt sehr viele Dinge in einem modernen RDBMS, die man nicht machen muss, aber machen kann. Man verschenkt große Teile ihrer Haupteinsatzgründe, wenn man es nicht tut.
Je mehr dieser Features man nicht nutzt, desto mehr nähert man sich von der Arbeitsweise an die Nutzung eines Editors an oder eines Excel Sheets an.
Man kann CSV nehmen statt ein vollwertiges RDBMS. Man kann sogar noch auf feste Spalten verzichten. Häufig reicht das vielleicht.

Eine DB ist nicht nur eine Sammlung von Datensätzen. Sie ist vor allem auch eine Sammlung von Regeln und Strukturen (Datenmodell).
Der Hammer: Ein Datenbankserver garantiert(!) die Einhaltung aller definierten Regeln. Klingt vielleicht banal, ist aber enorm.
Und es liegt auf der Hand: wenn ich keine Regeln (z.B. Foreign Keys) definiere, kann der Server auch solche Regeln nicht überwachen, geschweige denn einhalten.

In dem Zusammenhang spannend zum Verständnis:
Welche Unterschiede gibt es da zwischen RDBMS und noSQL Systemen?
Oder nicht ganz so krass, "Was passiert eigentlich, wenn mein Persistenzsystem nicht versteht, welche Klassen ich definiere?" (oder wenn ich nicht verstehe, was das Persistenzsystem daraus macht / was es eigentlich kann?)

Du kannst auch mal folgendes überlegen:
- wie ist auf Dauer meine Datenqualität in einem System, bei dem ich allein die DB und das zugreifende Programm schreibe
- wie ändert sich das mit mehreren Programmierern
- wie ändert sich das mit mehreren Programmen (und mehreren Programmierern)
Wie kannst Du die Antworten darauf systematisch (und positiv) beeinflussen?

Eine Datenbank kann für eine gute Datenqualität sorgen, sie hält garantiert alle definierten Regeln ein. Ein Stichwort in dem Zusammenhang noch: ACID; kannst Du mal im Internet nachlesen. Da steht sowieso viel mehr und Besseres, als ich hier schreiben kann.
 
Werbung:
DBFiddle und ähnliche Seiten sind toll, aber wie gesagt nur eine Luxusvariante davon, was ich Dir nahegelegt habe bzw. was in einem Programmierforum Standard ist:
Einfach die "Texte", also Code, den Du bei DBFiddle eingetragen hast, hier im Forum posten, das reicht. Bei Datenbankfragen beinhaltet der Code das Datenmodell, also Tabellen Definitionsskripte, Trigger-wenn vorhanden, Daten, also Insertskripte und die eigentlichen Abfragen.
Allein das Lesen der (vollständigen) Tabellendefinition hilft (den Helfern). Es würde bspw. alle Schlüsselfelder zeigen, ohne dass man ein einziges Wort darüber verlieren müsste.

Wenn Du selbst Dir Tabellen anguckst, um festzustellen, wie Du sie verknüpfen könntest, machst Du das scheinbar anhand der Spaltennamen. Das ist dann Glückssache, ob es klappt und ausreicht.
Wie gesagt, das Createskript der Tabelle enthält eigentlich diese Angaben explizit, wenn es ordentlich gemacht ist. Du musst dann nicht verstehen oder raten oder die Sprache kennen, in der die Spalte benannt wurde. Wenn Du gemäß Deines Jobs nur Abfragen bauen musst, kann es leider sein, dass du nicht mal das Recht hast, diese Infos über das Datenmodell in deiner IDE abzulesen. Und IDE können das natürlich darstellen, sofern es jemand definiert und freigegeben hat. (In diesem Fall sollte man diese Informationen allerdings auf anderem Weg zur Verfügung gestellt bekommen.)
Und nein, das Definieren von Schlüsseln oder Fremdschlüsseln ist nicht notwendig. Das ist ja das "Gefährliche", Bequeme, Blöde!
Ich kenne Systeme (käuflich), die diese Informationen extra nicht in der DB angeben, weil sie es geheim halten wollen. Sie wollen nicht von Dritten kopiert, gelesen, verstanden oder weiterverarbeitet werden.
Kann man so machen, hindert einen Neugierigen am Ende auch nicht, die Schlüsselfelder rauszufinden, hindert einen Böswilligen dann ebensowenig, Daten zu manipulieren.

Ich hab jetzt keine Lust eine Hausarbeit über Datenmodellierung und ihren Sinn zu schreiben.
Vielleicht mal so: Es gibt sehr viele Dinge in einem modernen RDBMS, die man nicht machen muss, aber machen kann. Man verschenkt große Teile ihrer Haupteinsatzgründe, wenn man es nicht tut.
Je mehr dieser Features man nicht nutzt, desto mehr nähert man sich von der Arbeitsweise an die Nutzung eines Editors an oder eines Excel Sheets an.
Man kann CSV nehmen statt ein vollwertiges RDBMS. Man kann sogar noch auf feste Spalten verzichten. Häufig reicht das vielleicht.

Eine DB ist nicht nur eine Sammlung von Datensätzen. Sie ist vor allem auch eine Sammlung von Regeln und Strukturen (Datenmodell).
Der Hammer: Ein Datenbankserver garantiert(!) die Einhaltung aller definierten Regeln. Klingt vielleicht banal, ist aber enorm.
Und es liegt auf der Hand: wenn ich keine Regeln (z.B. Foreign Keys) definiere, kann der Server auch solche Regeln nicht überwachen, geschweige denn einhalten.

In dem Zusammenhang spannend zum Verständnis:
Welche Unterschiede gibt es da zwischen RDBMS und noSQL Systemen?
Oder nicht ganz so krass, "Was passiert eigentlich, wenn mein Persistenzsystem nicht versteht, welche Klassen ich definiere?" (oder wenn ich nicht verstehe, was das Persistenzsystem daraus macht / was es eigentlich kann?)

Du kannst auch mal folgendes überlegen:
- wie ist auf Dauer meine Datenqualität in einem System, bei dem ich allein die DB und das zugreifende Programm schreibe
- wie ändert sich das mit mehreren Programmierern
- wie ändert sich das mit mehreren Programmen (und mehreren Programmierern)
Wie kannst Du die Antworten darauf systematisch (und positiv) beeinflussen?

Eine Datenbank kann für eine gute Datenqualität sorgen, sie hält garantiert alle definierten Regeln ein. Ein Stichwort in dem Zusammenhang noch: ACID; kannst Du mal im Internet nachlesen. Da steht sowieso viel mehr und Besseres, als ich hier schreiben kann.
Vielen Dank für die vielen Infos und hilfreichen Tipps, ich werde mich damit bei Zeiten genauer beschäftigen!
 
Zurück
Oben