| Autor |
Beitrag |
D. Annies
      
Beiträge: 1843
windows 7
D6 Enterprise, D7 Pers und TD 2006
|
Verfasst: So 22.07.07 20:29
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
      
Beiträge: 4106
Erhaltene Danke: 13
Delphi 2010 Pro; Delphi.Prism 2011 pro
|
Verfasst: 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.
_________________ Markus Kinzler.
|
|
D. Annies 
      
Beiträge: 1843
windows 7
D6 Enterprise, D7 Pers und TD 2006
|
Verfasst: 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
      
Beiträge: 4106
Erhaltene Danke: 13
Delphi 2010 Pro; Delphi.Prism 2011 pro
|
Verfasst: 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.
_________________ Markus Kinzler.
|
|
D. Annies 
      
Beiträge: 1843
windows 7
D6 Enterprise, D7 Pers und TD 2006
|
Verfasst: So 22.07.07 21:14
Hi, Markus,
kannst du mir dabei (auf die Sprüge) helfen?
Detlef
|
|
mkinzler
      
Beiträge: 4106
Erhaltene Danke: 13
Delphi 2010 Pro; Delphi.Prism 2011 pro
|
Verfasst: So 22.07.07 21:19
Poste mal die fehlende Tabelle, welche die Zuordnung festlegt.
_________________ Markus Kinzler.
|
|
Fabian W.
      
Beiträge: 1766
Win 7
D7 PE
|
Verfasst: 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 
      
Beiträge: 1843
windows 7
D6 Enterprise, D7 Pers und TD 2006
|
Verfasst: 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
      
Beiträge: 4106
Erhaltene Danke: 13
Delphi 2010 Pro; Delphi.Prism 2011 pro
|
Verfasst: 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; |
_________________ Markus Kinzler.
|
|
D. Annies 
      
Beiträge: 1843
windows 7
D6 Enterprise, D7 Pers und TD 2006
|
Verfasst: So 22.07.07 22:18
Hi, Markus,
erstmal danke für deine Antwort!
Das "Drehen" habe ich noch nicht verstanden.
Detlef
|
|
mkinzler
      
Beiträge: 4106
Erhaltene Danke: 13
Delphi 2010 Pro; Delphi.Prism 2011 pro
|
Verfasst: 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
_________________ Markus Kinzler.
|
|
D. Annies 
      
Beiträge: 1843
windows 7
D6 Enterprise, D7 Pers und TD 2006
|
Verfasst: So 22.07.07 22:24
Aha!
Dann werd ich mal ...
Detlef
|
|
D. Annies 
      
Beiträge: 1843
windows 7
D6 Enterprise, D7 Pers und TD 2006
|
Verfasst: 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 
|
|
Blawen
      
Beiträge: 616
Erhaltene Danke: 33
Win XP, Vista, 7
Delphi 5 Prof., BDS 2006 Prof. RAD Studio XE
|
Verfasst: 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  |
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
Delphi-Quelltext
Selbstverständlich kannst Du auch kombinieren.
_________________ Es kompilert, wir können ausliefern.
Und es kompiliert wieder - das Update ist fertig - bitte 100 Euro
|
|
D. Annies 
      
Beiträge: 1843
windows 7
D6 Enterprise, D7 Pers und TD 2006
|
Verfasst: 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
      
Beiträge: 616
Erhaltene Danke: 33
Win XP, Vista, 7
Delphi 5 Prof., BDS 2006 Prof. RAD Studio XE
|
Verfasst: 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
_________________ Es kompilert, wir können ausliefern.
Und es kompiliert wieder - das Update ist fertig - bitte 100 Euro
|
|
D. Annies 
      
Beiträge: 1843
windows 7
D6 Enterprise, D7 Pers und TD 2006
|
Verfasst: 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?
Gruß, Detlef
|
|
mkinzler
      
Beiträge: 4106
Erhaltene Danke: 13
Delphi 2010 Pro; Delphi.Prism 2011 pro
|
Verfasst: Di 24.07.07 19:45
In der Abfrage nicht, du kannst dies aber wie oben schon mal skizziert bei der Anzeige machen.
_________________ Markus Kinzler.
|
|
Blawen
      
Beiträge: 616
Erhaltene Danke: 33
Win XP, Vista, 7
Delphi 5 Prof., BDS 2006 Prof. RAD Studio XE
|
Verfasst: 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
_________________ Es kompilert, wir können ausliefern.
Und es kompiliert wieder - das Update ist fertig - bitte 100 Euro
|
|
alzaimar
      
Beiträge: 2889
Erhaltene Danke: 13
W2000, XP
D6E, BDS2006A, DevExpress
|
Verfasst: 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.
_________________ Na denn, dann. Bis dann, denn.
|
|