Entwickler-Ecke
Datenbanken - Group by und order by mit Memo-Feldern...
Killi - Mi 09.07.03 12:01
Titel: Group by und order by mit Memo-Feldern...
Hi!
Ich hab ne ziemlich lange SQL-Anweisung mit vielen Feldern, darin auch ein Memo-Feld (recallText.Text) - das will er aber so nicht haben:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20:
| QDruck.SQl.Add('Select kunden.Karteikarten_nr, kunden.Nachname, kunden.Vorname, kunden.Straße, kunden.Nummer, kunden.PLZ, kunden.Ort,'); QDruck.SQL.Add(' recallText.Anrede, recallText.Text'); QDruck.SQl.Add(' Max(termine.Datum) as MaxTermin from kunden, termine, recallText where (kunden.Recall = ''True'') and (termine.KID = kunden.KID) and (Erledigt = ''True'')'); QDruck.SQl.Add(' and (Kunden.RID = recallText.RID)'); QDruck.SQl.Add(' and (kunden.Straße <> '''') and (kunden.PLZ <> '''') and (kunden.Ort <> '''')'); QDruck.SQL.Add(' and (((kunden.RecallZeit = ''1'') and (termine.Datum < ''' + DateToStr(Jahr1) + '''))'); QDruck.SQl.Add(' or ((kunden.RecallZeit = ''2'') and (termine.Datum < ''' + DateToStr(Jahr2) + '''))'); QDruck.SQl.Add(' or ((kunden.RecallZeit = ''3'') and (termine.Datum < ''' + DateToStr(Jahr3) + '''))'); QDruck.SQl.Add(' or ((kunden.RecallZeit = ''4'') and (termine.Datum < ''' + DateToStr(Jahr4) + '''))'); QDruck.SQl.Add(' or ((kunden.RecallZeit = ''5'') and (termine.Datum < ''' + DateToStr(Jahr5) + '''))'); QDruck.SQl.Add(' or ((kunden.RecallZeit = ''6'') and (termine.Datum < ''' + DateToStr(Jahr6) + '''))'); QDruck.SQl.Add(' or ((kunden.RecallZeit = ''7'') and (termine.Datum < ''' + DateToStr(Jahr7) + '''))'); QDruck.SQl.Add(' or ((kunden.RecallZeit = ''8'') and (termine.Datum < ''' + DateToStr(Jahr8) + '''))'); QDruck.SQl.Add(' or ((kunden.RecallZeit = ''9'') and (termine.Datum < ''' + DateToStr(Jahr9) + '''))'); QDruck.SQl.Add(' or ((kunden.RecallZeit = ''10'') and (termine.Datum < ''' + DateToStr(Jahr10) + '''))'); QDruck.SQl.Add(' or ((kunden.RecallZeit = ''11'') and (termine.Datum < ''' + DateToStr(Jahr11) + '''))'); QDruck.SQl.Add(' or ((kunden.RecallZeit = ''12'') and (termine.Datum < ''' + DateToStr(Jahr12) + ''')))');
QDruck.SQl.Add(' group by kunden.Karteikarten_nr, kunden.Nachname, kunden.Vorname, kunden.Straße, kunden.Nummer, kunden.PLZ, kunden.Ort, '); QDruck.SQl.Add(' recallText.Anrede, recallText.Text order by kunden.Nachname ASC, kunden.Vorname ASC, termine.MaxTermin DESC'); |
er meint ich könnte in group by keine BLOB Memos haben und wenn ichs rausnehme dann meint er er bräuchte es! Das Feld MUSS aber in dieser ANweisung stehen da ich damit einen AUsdruck machen will....was soll ich jetzt machen?
Moderiert von
Tino: Delphi-Tags hinzugefügt.
neojones - Do 10.07.03 09:19
Wenn ich das richtig sehe gehört ins GROUP BY nur "kunden.Karteikarten_nr".
Viele Grüße,
Matthias
Killi - Do 10.07.03 10:45
Nein, wieso sollte da nur Karteikarten_nr reingehören? Da müssen alle Felder rein - sonst kommt ne Meldung "Wenn ein GROUP BY existiert, müssen alle einfachen Felder in GROUP BY vorhanden sein"!
Und so komm ich zu meinem Problem mit der Memo - es ist anscheinend n einfaches Feld, aber das BLOB MEmo (wie es dann schließlich in der DB gespeichert wird) nicht mehr, also will er das nicht.....
neojones - Do 10.07.03 13:00
Äääähmmm ... was für ne Datenbank benutzt Du denn? Das ist nicht ANSI-konform wenn ins GROUP BY alle Felder müssen. Genaugenommen ists sogar absoluter Quatsch das so zu machen.
Viele Grüße,
Matthias
Killi - Do 10.07.03 13:34
Paradox-Tabelle........
Wieso Quatsch? Das hat mir einer empfohlen da ich vorher schon ein Problem hatte - guck hier mal:
http://www.delphi-forum.de/viewtopic.php?p=77220
Mit dem Code gings dann wunderbar - und der hatte group by drin......
neojones - Do 10.07.03 13:50
Also, das GROUP BY dient dazu, innerhalb von Gruppenfunktionen (SUM, MAX, ...) festzulegen, auf welche Spalte gruppiert werden soll. Ich verstehe den Sinn und Zweck nicht, was es bewirken soll, auf alle Spalten zu gruppieren.
Viele Grüße,
Matthias
Killi - Do 10.07.03 15:56
Tja...ich auch nicht ;-)
Aber das group by brauche ich - wie du ja schon selber gesagt hast - weil ich ein MAX drinhabe...und wenn ich ein group by drin habe, müssen alle einfachen Felder - so will es delphi - darin enthalten sein!
neojones - Do 10.07.03 17:02
Eventuell wirds dadurch verursacht, dass Du die Tabellen als Equi-Join verknüpfst. Das an sich ist schonmal ein Performance-Problem, weil dabei zuerst das kartesische Produkt aufgebaut wird und erst im kartesichen Produkt die Validierung erfolgt. Ausserdem fällt mir auf, dass zwischen dem MAX und dem "recallText.Text" das Komma fehlt.
Sinnvollerweise sollte man den JOIN so aufbauen (Habe im Where die Klammern entfernt, die sind bei AND's nicht nötig, ausserdem das Komma gesetzt und einen LEFT JOIN statt Equi verwendet und das GROUP BY nach ANSI gesetzt!). Wenn ich das richtig verstehe willst Du nur die Kundendaten und die Anzahl der Termine? Dann sollte es so gehen??
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22:
| QDruck.SQl.Add('Select kunden.Karteikarten_nr, kunden.Nachname, kunden.Vorname, kunden.Straße, kunden.Nummer, kunden.PLZ, kunden.Ort,'); QDruck.SQL.Add(' recallText.Anrede, recallText.Text,'); QDruck.SQl.Add(' Max(termine.Datum) as MaxTermin from kunden'); QDruck.SQl.Add(' LEFT JOIN termine ON termine.KID=kunden.KID'); QDruck.SQl.Add(' WHERE kunden.Recall="True" AND Erledigt="True"'); QDruck.SQl.Add(' and Kunden.RID = recallText.RID'); QDruck.SQl.Add(' and kunden.Straße <> '''') and kunden.PLZ <> '''')and kunden.Ort <> '''''); QDruck.SQL.Add(' and (((kunden.RecallZeit = ''1'') and (termine.Datum < ''' + DateToStr(Jahr1) + '''))'); QDruck.SQl.Add(' or ((kunden.RecallZeit = ''2'') and (termine.Datum < ''' + DateToStr(Jahr2) + '''))'); QDruck.SQl.Add(' or ((kunden.RecallZeit = ''3'') and (termine.Datum < ''' + DateToStr(Jahr3) + '''))'); QDruck.SQl.Add(' or ((kunden.RecallZeit = ''4'') and (termine.Datum < ''' + DateToStr(Jahr4) + '''))'); QDruck.SQl.Add(' or ((kunden.RecallZeit = ''5'') and (termine.Datum < ''' + DateToStr(Jahr5) + '''))'); QDruck.SQl.Add(' or ((kunden.RecallZeit = ''6'') and (termine.Datum < ''' + DateToStr(Jahr6) + '''))'); QDruck.SQl.Add(' or ((kunden.RecallZeit = ''7'') and (termine.Datum < ''' + DateToStr(Jahr7) + '''))'); QDruck.SQl.Add(' or ((kunden.RecallZeit = ''8'') and (termine.Datum < ''' + DateToStr(Jahr8) + '''))'); QDruck.SQl.Add(' or ((kunden.RecallZeit = ''9'') and (termine.Datum < ''' + DateToStr(Jahr9) + '''))'); QDruck.SQl.Add(' or ((kunden.RecallZeit = ''10'') and (termine.Datum < ''' + DateToStr(Jahr10) + '''))'); QDruck.SQl.Add(' or ((kunden.RecallZeit = ''11'') and (termine.Datum < ''' + DateToStr(Jahr11) + '''))'); QDruck.SQl.Add(' or ((kunden.RecallZeit = ''12'') and (termine.Datum < ''' + DateToStr(Jahr12) + ''')))');
QDruck.SQl.Add(' group by kunden.Karteikarten_nr order by kunden.Nachname ASC, kunden.Vorname ASC, termine.MaxTermin DESC'); |
Noch was: Das ASC kannst Dir eigentlich auch sparen weil standardmäßig ASC sortiert wird.
Killi - Fr 11.07.03 10:55
OK, ich tu mal so als hätt ich alles verstanden, vor allem wegen deinen iritierenden "Wo kämen wir hin"-Satz...
Da müsste allerdings noch EINE Tabelle hinzukommen: recallText - wie mach ich das bei Left Join und diesem on?
neojones - Fr 11.07.03 11:07
Einfach nochmal einen druntersetzen.
Du schreibst immer
Quelltext
1:
| LEFT JOIN Tabelle ON Tabelle1.Feld = Tabelle2.ZugeordnetesFeld |
Das "ON" gibt immer die Verknüpfungsbedingung an. Man kann im ON auch AND und OR benutzen, falls das nötig ist.
Man kann einen JOIN auch auf eine Tabelle beziehen, die in einem JOIN davor steht.
Killi - Fr 11.07.03 11:08
Habs jetzt so gemacht (du hattest übrigens 2 ")" Klammern zuviel drin):
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22:
| QDruck.SQl.Add('Select kunden.Karteikarten_nr, kunden.Nachname, kunden.Vorname, kunden.Straße, kunden.Nummer, kunden.PLZ, kunden.Ort,'); QDruck.SQL.Add(' recallText.Anrede, recallText.Text,'); QDruck.SQl.Add(' Max(termine.Datum) as MaxTermin from kunden'); QDruck.SQl.Add(' LEFT JOIN termine ON termine.KID=kunden.KID'); QDruck.SQl.Add(' LEFT JOIN recallText ON kunden.RID=recallText.RID'); QDruck.SQl.Add(' WHERE kunden.Recall="True" AND Erledigt="True"'); QDruck.SQl.Add(' and Kunden.RID = recallText.RID'); QDruck.SQl.Add(' and kunden.Straße <> '''' and kunden.PLZ <> '''' and kunden.Ort <> '''''); QDruck.SQL.Add(' and (((kunden.RecallZeit = ''1'') and (termine.Datum < ''' + DateToStr(Jahr1) + '''))'); QDruck.SQl.Add(' or ((kunden.RecallZeit = ''2'') and (termine.Datum < ''' + DateToStr(Jahr2) + '''))'); QDruck.SQl.Add(' or ((kunden.RecallZeit = ''3'') and (termine.Datum < ''' + DateToStr(Jahr3) + '''))'); QDruck.SQl.Add(' or ((kunden.RecallZeit = ''4'') and (termine.Datum < ''' + DateToStr(Jahr4) + '''))'); QDruck.SQl.Add(' or ((kunden.RecallZeit = ''5'') and (termine.Datum < ''' + DateToStr(Jahr5) + '''))'); QDruck.SQl.Add(' or ((kunden.RecallZeit = ''6'') and (termine.Datum < ''' + DateToStr(Jahr6) + '''))'); QDruck.SQl.Add(' or ((kunden.RecallZeit = ''7'') and (termine.Datum < ''' + DateToStr(Jahr7) + '''))'); QDruck.SQl.Add(' or ((kunden.RecallZeit = ''8'') and (termine.Datum < ''' + DateToStr(Jahr8) + '''))'); QDruck.SQl.Add(' or ((kunden.RecallZeit = ''9'') and (termine.Datum < ''' + DateToStr(Jahr9) + '''))'); QDruck.SQl.Add(' or ((kunden.RecallZeit = ''10'') and (termine.Datum < ''' + DateToStr(Jahr10) + '''))'); QDruck.SQl.Add(' or ((kunden.RecallZeit = ''11'') and (termine.Datum < ''' + DateToStr(Jahr11) + '''))'); QDruck.SQl.Add(' or ((kunden.RecallZeit = ''12'') and (termine.Datum < ''' + DateToStr(Jahr12) + ''')))');
QDruck.SQl.Add(' group by kunden.Karteikarten_nr order by kunden.Nachname ASC, kunden.Vorname ASC, termine.MaxTermin DESC'); |
neojones - Fr 11.07.03 11:09
Ooops, sorry!
Funktionierts so? Auch die Summenabbildung?
Killi - Fr 11.07.03 14:10
Nein, so tuts eben nicht - so will er wieder jedes einfache Feld in group by haben....hier die Meldung
| Zitat: |
| wenn ein GROUP BY existiert, muß sich jedes einfache Feld in den Projektoren im GROUP BY befinden |
Moderiert von
Tino: Quote-Tags hinzugefügt.
Killi - Mo 14.07.03 08:47
Jetzt weiß keiner mehr was, oder...?
So n Sch... :cry:
neojones - Mo 14.07.03 09:07
Ich bin mit meinem Latein am Ende (Und das, obwohl ich sogar ein großes Latinum hab *g*). Ich hab am Samstag nochmal im ANSI-92-Standard nachgelesen. Laut dem müsste es so eigentlich gehen *kotz*
Hat sonst noch jemand eine Idee?
Killi - Mo 14.07.03 11:30
Probiers doch mal aus - Paradox-Tabelle mit nem Text o.ä. UND nem Memo-Feld...dann verknüpf die Tabelle mit ner anderen einfachen Tabelle (überne ID oder so) und setz dann n group by - das mag er bloß nicht wegen dem BLOB-Feld das das Memo in der tabelle erzeugt...das gesamte Memo wird ja woanders gespeichert...und das ist das Problem - das SQl weiß es wohl nicht und sieht es so als "einfaches Feld", darum müsste es im group by stehen - wenn mans ausführen will merkt ers endlich....
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!