Entwickler-Ecke

Datenbanken - [MSSQL 2000] Mehrere geschachtelte Zeilen aus einer Tabelle


jojo-sp - Do 18.10.07 18:10
Titel: [MSSQL 2000] Mehrere geschachtelte Zeilen aus einer Tabelle
Hallo,

Grübel gerade an einer Abfrage, mit der ich möglichst einfach aus einer Tabelle mehrere Zeilen lesen kann, die untereinander Verknüpft sind.

Es gibt im Prinzip eine Masterzeile, die Daten enthält und auf mehrere weitere Zeilen der Tabelle zeigen kann.


Quelltext
1:
2:
3:
4:
ID - Daten1 - Daten2 - Daten3 - pID1 - pID2 - pID3 - ...
1  - xyz    - 123    - x1y2z3 - 2    - 3    - NULL - ...
2  - abc    - 987    - a9b8c7 - NULL - NULL - NULL - ...
3  - äöü    - 546    - ä5ö4ü6 - NULL - NULL - NULL - ...

Die Zeile 1 bzw. ID 1 wäre in diesem Fall die Masterzeile, die in den Feldern pID1 und pID2 auf weitere Zeilen der Tabelle zeigen.

Ich möchte jetzt die Daten als Ergebnis aller Zeilen durch meine Abfrage erhalten.

Da es sich um einer Tabelle handelt bringen mir Abfragen mit join, having, union o.ä. nichts oder bin ich nur zu doof...?


ene - Fr 19.10.07 07:35

Moin,

vielleicht hab ichs ja nicht verstanden, aber woher soll ich wissen, dass in 1 die 2 und 3 kommen? Und wie weit soll das gehen?


Miri - Fr 19.10.07 07:38

vor allem: woher weißt du, dass 1 die "Masterzeile" ist?!
Wie soll die Ausgabe hinterher aussehen und wie viele pIDs hast du drin?
Wenns noch mehr sind, wäre es nämlich einfacher, das Konzept zu ändern... (Normalisieren ist das Stichwort!!!)


@ene das weiß er aus den Feldern pID1 und pID2


ene - Fr 19.10.07 07:52

*knietsch* Ich dachte das wäre das Ergebnis...wie soll das Ergebnis denn sein? Einfach die 3 Zeilen untereinander? Und Miri's Ratschlag ist definitiv sinnvoll, vor allem wenn man sich die Feldbezeichnungen ansieht. Sich wiederholende Spalten widersprechen immer der Normalisierung.


jasocul - Fr 19.10.07 08:00

Ich denke, hier hilft das Stichwort Subselect.


ene - Fr 19.10.07 08:24

SubSelect sähe so aus:


SQL-Anweisung
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
SELECT 
  * 
FROM 
  tbl 
WHERE 
    (ID IN (SELECT pID FROM tbl WHERE ID = 1)) 
  OR 
    (ID IN (SELECT pID1 FROM tbl WHERE ID = 1)) 
  OR 
    ID = 1


Wobei in einer SP auf dem Server vielleicht das Arbeiten mit temporären Tabellen sinnvoller wäre. Denn SubSelect können zu richtigen Performancebremsen werden und die ganzen IN's werden auch nicht mehr Geschwindigkeit bringen.


jojo-sp - Fr 19.10.07 08:50

Normalformen habe ich auf der Schule kennen gelernt :-)

Jedoch wurde diese Tabelle bzw. Datenbank nicht von mir erstellt, sondern ist ein bestehendes Bürosystem bei einem Kunden.
Da ich Daten zur Produktion benötige, muss ich mir die Sachen anhand der "Master" ID aus der Tabelle raussaugen, wobei ich die MasterID auch nur wieder über einen Join mit einer anderen Tabelle erhalte.
Ist ein ganz fieses Konstrukt, bei dem sich einige im Grabe umdrehen werden ... ;-)

Wollte eigentlich nicht mit temporären Tabellen arbeiten, aber es ist sicher die beste Lösung :-(


ene - Fr 19.10.07 08:59

Was spricht gegen TempTabellen? Auf dem Server bestehen sie doch nur innerhalb der SP :nixweiss:


jojo-sp - Fr 19.10.07 09:24

Nichts, hatte nur gehofft ein einfaches SQL Gebilde zu basteln, dass nicht aus Millionen von Abfragen besteht.

Das Subselect funktioniert, jedoch erhalte ich die "Masterzeile" nicht unbedingt als ersten Datensatz. Ich erhalte die Zeilen nur in aufsteigender Reihenfolge. Da die Ergebnisse des Subselects irgendwo in der Tabelle sein können, wäre die Reihenfolge dann nicht richtig.

Da ich keine Informationen der Zeilen nutzen kann, um diese in der richtigen Reihenfolge zu sortieren (auch nicht die ID) , muss ich immer davon Ausgehen, dass die DB die Daten in der richtigen Reihenfolge ausgibt. Daher werde ich mir ein temporäre Tabelle bauen, in der ich die Information, um was es sich handelt beifügen werde.

So, in diesem Sinne:

"Heinrich, mir grauts vor dir!"


jasocul - Fr 19.10.07 09:26

user profile iconjojo-sp hat folgendes geschrieben:
Da ich keine Informationen der Zeilen nutzen kann, um diese in der richtigen Reihenfolge zu sortieren (auch nicht die ID) , muss ich immer davon Ausgehen, dass die DB die Daten in der richtigen Reihenfolge ausgibt.
:shock: Wer baut denn sowas? :shock: Informiere bloß den Kunden, dass es da zu Problemen kommen kann.

user profile iconjojo-sp hat folgendes geschrieben:
"Heinrich, mir grauts vor dir!"
Das trifft den Kern der Sache.


jojo-sp - Fr 19.10.07 09:37

Ein etwas größerer Betrieb, aus dem Land, wo sie in die Schluchten Kacken und Petitionen gegen ihre eigene Nationalmannschaft unterschreiben ;-)


alzaimar - Fr 19.10.07 10:03

user profile iconjojo-sp hat folgendes geschrieben:

Da ich keine Informationen der Zeilen nutzen kann, um diese in der richtigen Reihenfolge zu sortieren (auch nicht die ID) , muss ich immer davon Ausgehen, dass die DB die Daten in der richtigen Reihenfolge ausgibt.

MSSQL ist -wie alle relationalen DBMS- eine mengenbasierte Datenbank, daher der Name 'Dataset'. Wie wir alle wissen, sind Mengen per se unsortiert.

MSSQL wird dir die Daten zufällig (wohl aber i.A. nach dem Primary-Key sortiert) ausgeben, aber verlassen kann und soll man sich darauf nicht. Um eine explizite Reihenfolge der Daten zu erhalten, muss man die ORDER BY Klausel verwenden.


jasocul - Fr 19.10.07 10:06

Das meinte ich mit:
user profile iconjasocul hat folgendes geschrieben:
Informiere bloß den Kunden, dass es da zu Problemen kommen kann.
Ich bin aber davon ausgegangen, dass user profile iconjojo-sp die Details klar sind.


Miri - Fr 19.10.07 10:39

Vielleicht solltest du ein Angebot über ein vernünftiges System fertig machen und dem Kunden zuschicken?! ;-)


jojo-sp - Fr 19.10.07 10:48

Gott bewahre,

die Datenbank besteht aus 100 Tabellen mit durchschnittlich 75 Feldern. Bis ich da eine geeignete Kalkulations- / Bürosoftware und Datenbank geschrieben habe, vergehen Jahre...
und wir machen (noch) keine Systeme zur AV (Arbeitsvorbereitung), sondern nur zur Produktion.

Das System ist im Prinzip SAP in Miniatur.


Miri - Fr 19.10.07 10:50

Dann bleibt dir wohl kaum was anderes übrig, als über eine Stored Procedure zu gehen und "manuell" zu sortieren (ich gehe jetzt mal davon aus, dass du den Mastersatz oben haben willst und die anderen sortiert darunter...)


Agawain - Fr 19.10.07 11:47

Hi

wäre in dem Fall eine Überlegung wert, die Tabelle dauerhaft über Trigger zu normalisieren, sofern es die Anwendung zuläßt.

Solche Verwurschtelungen machen langfristig viel Arbeit, so daß sich je nach noch zu erfüllenden Aufgaben im Projekt, der Aufwand lohnen könnte.

Außerdem hätte es den Vorteil, dass Du die Kontrolle über die Datenerstellung erhältst und in Deinem Programm diese Verrenkungen nicht mitmachen mußt.

Hab hier nämlich auch so ein Ungetüm...und als ich die von dem Programm erzeugten Inkonsistenzen beseitigen mußte, durfte ich überrascht festellen, daß der Mastersatz zuletzt weggeschrieben wurde, was in dem Fall sogar günstig war, weil dadurch die Inkonsistenz auf jeden Fall auffällt.

Gruß

Aga


jojo-sp - Fr 19.10.07 12:03

Ich kann leider keine Änderungen an er Tabelle vornhemen, da wir im Prinzip nur Gast sind.
Ich kann nur ein Statusbit setzen, welches sagt, dass ich die Daten bereits eingelesen habe, damit man im Büro weiß, dass die Daten bereits in Produktion sind.

Ich glaube, ich machs auf die etwas unfeinere Art und hole zuerst den Mastersatz in meine App und danach Stück für Stück die anderen Datensätze. Da es in dem Moment nicht auf Geschwindigkeit ankommt und der Büroserver nicht an Überlastung stirbt, sollte das am einfachsten sein.