Entwickler-Ecke
Datenbanken - "dynamische" SQL-Tabelle?
D. Annies - So 22.07.07 20:29
Titel: "dynamische" SQL-Tabelle?
Hi, Delpher,
Es gibt, sagen wir vier personen (mit verschiedenen Namen) die mehrere, auch verschiedene Artikel geliehen haben.
Gibt es die Möglichkeit, das in einer SQL-Tabelle durch einen SQL-Befehl darzustellen?
Beispiel:
name.dbf
Meier
Müller
Peters
Schulz
artikel.dbf
Boot
Lampe
Säge
Hammer
Zange
gewünschtes Ausgabeergebnis
Name Artikel_01 Artikel_02 Artikel_03 Artikel_04
Meier Boot Lampe Säge Hammer
Müller Lampe Hammer Zange
Schulz Boot Säge Hammer
Versuch 1:
Select * from name.dbf n artikel.dbf a
where (n.name = a.name) order by ...
Also, gewünscht ist, dass die verschiedenen Artikel nebeneinander stehen, man weiß also zunächst nicht, wie viele Spalten die Ergebnistabelle hat!
Vielen Dank für Hilfe
Detlef
mkinzler - So 22.07.07 20:38
Durch ein einfaches Statement nicht, da ja die Spaltenanzahl, wie schon erkannt flexibel ist. Eine Möglichkeit wäre es die Artikel in einer Spalte mit Trennzeichen zu bringen.
D. Annies - So 22.07.07 21:01
Hi, Markus,
könnte ich festlegen, dass die Ergebnistabelle 25 Spalten hat, weil ich weiß, dass jemand sicher - nicht mehr als 25 Artikel haben kann?
Gruß, Detlef
mkinzler - So 22.07.07 21:05
Dann würde es trotzdem Probleme mit dBase geben, da hier keine Limitierung möglich ist. Ich würde eine Normale (Join-)Abfrage nehmen und die Ergennisse erst bei der Anzeige zu drehen.
D. Annies - So 22.07.07 21:14
Hi, Markus,
kannst du mir dabei (auf die Sprüge) helfen?
8) :arrow: :idea: :D
Detlef
mkinzler - So 22.07.07 21:19
Poste mal die fehlende Tabelle, welche die Zuordnung festlegt.
Fabian W. - So 22.07.07 21:29
Mach das doch so:
Du nimmst eine Tabelle für die Leute die etwas ausleihen (ID, Name) und eine Tabelle für die Gegenstände, die die Leute geliehen haben (Kunde_ID, Gegenstand).
Die Abfrage geht dann so: select balbla... where Kunde_ID = ID
mfg
D. Annies - So 22.07.07 21:40
Hi, Markus,
die fehlende Tabelle hat den Aufbau:
Artikel Name Leihdatum
Hammer Meier 05.07.2007
Hammer Müller 06.07.2007
Säge Meier 03.07.2007
usw., (als Beispiel)
Detlef
mkinzler - So 22.07.07 21:49
Ich würde die Klartextbezeichnungen der Ausleihe durch echte Fremschlüssel ersetzen:
name.dbf
ID Name1 Meier
2 Müller
3 Peters
4 Schulz
artikel.dbf
ID Bez1 Boot
2 Lampe
3 Säge
4 Hammer
5 Zange
ausleihe.dbf
Artikel Name Leihdatum4 1 05.07.2007
4 2 06.07.2007
3 1 03.07.2007
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8:
| id:=0; Query.SQL.Text := 'select a.bez, n.id as nid, n.name, l.leihdatum from ausleihe l join name n join n.id = l.name and artikel a on a.id = l.artikel order by l.name'; Query.Open; while not Query.EOF do begin if Query1.FieldByName('nid').Value <> id then ... end; |
D. Annies - So 22.07.07 22:18
Hi, Markus,
erstmal danke für deine Antwort!
Das "Drehen" habe ich noch nicht verstanden.
Detlef
mkinzler - So 22.07.07 22:20
Solange sich die Id des Ausleihers nicht ändert wird ein neue Spalte erzeugt, sonst neue Zeile.
Hammer 1 Meier 05.07.2007
Säge 1 Meier 03.07.2007
Hammer 2 Müller 06.07.2007
=>
Meier Hammer Säge
Müller Hammer
D. Annies - So 22.07.07 22:24
Aha!
Dann werd ich mal ... :P
Detlef
D. Annies - So 22.07.07 22:34
Sorry, Markus, ich habe etwas (wichtiges) übersehen:
Name.dbf
Meier Lübeck
Müller Hamburg
Peters Lübeck
Schulz Lübeck
Die Auswertung soll nach dem Ort erfolgen! (!)
Leihtabelle also:
Artikel Name Leihdatum Ort
.. .
Detlef :oops:
Blawen - Mo 23.07.07 00:48
D. Annies hat folgendes geschrieben: |
Sorry, Markus, ich habe etwas (wichtiges) übersehen:
Name.dbf
Meier Lübeck
Müller Hamburg
Peters Lübeck
Schulz Lübeck
Die Auswertung soll nach dem Ort erfolgen! (!)
Leihtabelle also:
Artikel Name Leihdatum Ort
.. .
Detlef :oops: |
Was spricht dagegen, die Tabelle zu erweitern und entsprechend sortieren zu lassen?
ID Name Wohnort
1 Meier Lübeck
2 Müller Hamburg
3 Peters Lübeck
4 Schulz Lübeck
Selbstverständlich kannst Du auch kombinieren.
D. Annies - Mo 23.07.07 11:09
Hi, Markus und Blawen,
1. kann es sein, dass der SQL-Befehl falsch ist?
... join name n join n.id = l.name ...
2. wie "geht" denn nun die neue Zeile?
... then // neue Zeile
Danke für weitere Unterstützung,
Detlef
Blawen - Mo 23.07.07 22:12
Ich habe ehrlich gesagt im Moment nicht den Überblick über Deine effektive DB-Struktur und Mutmassungen liebe ich nicht. Daher poste ich mal ein einfaches und universelles Beispiel:
SQL-Anweisung
1: 2: 3: 4: 5: 6: 7: 8:
| Select * From MITARBEITER INNER JOIN (KONTAKTDATEN,PLZ,LAENDER,ABTEILUNG) ON MITARBEITER.KONTAKTDATEN_ID = KONTAKTDATEN.KONTAKTDATEN_ID AND MITARBEITER.PERSONALNUMMER Like "' + Edit_Suche.Text + '%" AND KONTAKTDATEN.PLZ_ID = PLZ.PLZ_ID AND KONTAKTDATEN.ABTEILUNG_ID = ABTEILUNG.ABTEILUNG_ID AND PLZ.LAENDER_ID = LAENDER.LAND_ID ORDER by KONTAKTDATEN.Nachname DESC, KONTAKTDATEN.VORNAME DESC |
Hier existieren 4 Tabellen
- Mitarbeiter (spez. MA-Daten)
- Kontaktdaten (Sammel-DB für alle "Kontakte" - inkl. MA)
- PLZ (Postleitzahlen und entsprechende Ortschaften)
- Land (Länderverzeichnis)
Ausgegeben werden sollen diejenigen Datensätze der MA, bei welchen die Personalnummer mit den gleichen Zeichen beginnen, welche im Edit-Feld stehen.Moderiert von
UGrohne: Delphi- durch SQL-Tags ersetzt
D. Annies - Di 24.07.07 11:36
Hi, Blawen (&Markus)
danke für deine Mühe, das ist alles so korrekt, ich bekomme die gewünschten Daten, aber wie bekomme ich sie nebeneinander statt untereinander? - Oder geht das nicht? :cry:
Gruß, Detlef
mkinzler - Di 24.07.07 19:45
In der Abfrage nicht, du kannst dies aber wie oben schon mal skizziert bei der Anzeige machen.
Blawen - Di 24.07.07 23:57
mkinzler hat folgendes geschrieben: |
| In der Abfrage nicht, du kannst dies aber wie oben schon mal skizziert bei der Anzeige machen. |
Oder anders ausgedrückt:
Liste durchgehen und manuell in einem StringGrid eintragen:
- Gleicher Kunde -> Eintrag in neuer Spalte
- Neuer Kunde -> Neue Zeile beginnen
alzaimar - Mi 25.07.07 08:36
Um die Artikel nebeneinander zu bekommen, bietet sich eine Pivot-Tabelle (Crosstab) an. Dazu sollten die einzelnen Artikel je Name/Ort durchnumeriert werden. Alle Artikel mit gleichen Sequenznummer kommen dann in die selbe Spalte.
Das kann man in SQL lösen, aber ich finde das keine besonders gute Idee, da man das notwendige SQL-Kommando zur Laufzeit erstellen muss. Als Übung wäre es allerdings ein guter Brainteaser. Wenn es sich allerdings um sehr viele Daten handelt, kann eine Lösung in SQL performanter sein, da das notwendige Datenschaufeln im Server stattfindet.
Beispiel;
Nehmen wir an, Du möchtest eine Tabelle der Form
Name | Artikel_0 | Artikel_1 | ..... | Artikel_N
Wir benötigen eine temporäre Tabelle (=ZwischenResultat) der Form (Name, Artikel, ArtikelSeqNr). Die ArtikelSeqNr beginnt für jeden Namen bei 0 und ordnet die Artikel je Namen. Zunächst musst Du die höchste Artikelsequenznummer ermitteln. Das ergibt die Anzahl der Artikelspalten (Nennen wir diesen Wert 'N').
Anschließend bastelst Du dir das SQL-Kommando in etwa so zusammen (im Einzelnen ist es abhängig vom SQL-Dialekt):
SQL-Anweisung
1: 2: 3: 4: 5: 6: 7:
| select Name, (case when ArtikelSeqNr = 0 then Artikel else null end) as Artikel_0, (case when ArtikelSeqNr = 1 then Artikel else null end) as Artikel_1, ... (case when ArtikelSeqNr = N then Artikel else null end) as Artikel_N from ZwischenResultat group by Name |
Bleibt nun noch das Problem, wie man das Zwischenresultat erstellt. Dazu müssen wir eine totale Ordnung auf den Artikeln aufbauen. Entweder alphabetisch, oder wir nehmen einfach die ID der von MKinzler vorgeschlagenen Artikel-Tabelle. Die Artikelsequenznummer wäre dann die Anzahl der Artikel eines Namens, deren ID kleiner ist, als die ID des Artikel selbst. Hu? Klingt kompliziert, ist es aber nicht.
Ich habe mir erlaubt, die Feldbezeichner der Tabelle 'Ausleihe' etwas zu ändern: Name=>NameID und Artikel=>ArtikelID
SQL-Anweisung
1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| select Name.Name, Artikel.Artikel, (select count (*) from Ausleihe X where X.NameID = Name.ID and X.ArtikelID < Artikel.ID ) as ArtikelSeqNr from Name Join Ausleihe on Name.ID = Ausleihe.NameID Join Artikel on Artikel.ID = Ausleihe.ArtikelID |
(Ungetestet und aus dem Kopf runtergerasselt)
Blöderweise arbeitest Du mit DBase, sodaß es sein kann, das Du das wirklich so nicht geht und Du -wie Blawen meint- ein Stringgrid bastelt must. Als Denkanstoß und Proof-Of-Concept sollte mein Ansatz aber schon reichen.
D. Annies - Mi 25.07.07 09:50
Hi, Delpher-Helfer!
Ihr drei seid ja ordentlich am Ackern, vielen Dank bisher.
Die Anregungen werde ich jetzt verarbeiten und anpassen.
Komisch, dass dazu auch im Netz so gut wie nichts steht; es ist doch technisch gesehen nichts anderes als ein (einstufiger!) Gruppenwechsel!! - und da interessiert mich eine SQL-Lösung etwas mehr als eine Stringgrid-Lösung. Aber wenn das zu schwierig sein sollte, muss ich es lassen - aber erstmal beißen ...
Danke und Gruß,
Detlef
P.S. wenn euch noch was einfällt ...
D. Annies - Do 26.07.07 22:37
Wollte mich nur mal melden! Bin noch dabei.
Danke, melde mich wieder,
Detlef
D. Annies - So 29.07.07 19:54
Hi,
ich werde es mit einem Stringgrid machen ... :cry: ... müssen, ich kriege es anders nicht gebacken. - Man muss auch seine - oder die SQL- Grenzen erkennen.
Danke für eure Ideen,
Detlef
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!