Entwickler-Ecke
Datenbanken - Query: die besten der Klassen?
D. Annies - Di 30.06.09 13:48
Titel: Query: die besten der Klassen?
Hi, Delpher,
die folgende Query hat die Fehlermeldung:
Feld in order by muss im Resultat enthalten sein.
Delphi-Quelltext
1: 2: 3: 4:
| query1.SQL.Text := format('select S.geschlecht, max(S.punkte), S.klasse, S.name, S.vorname from "%s" S ' + 'where (S.Punkte > 0) '+ 'order by S.geschlecht, S.punkte, S.Klasse, S.name, S.vorname', [Table2.tablename]); |
Es soll der jeweils beste / die beste aus 6 verschiedenen Klassen angezeigt werden.
Danke für Hilfe,
Detlef
D. Annies - Di 30.06.09 14:12
Bin jetzt an der folgenden Stelle, aber immer noch fehlerhaft:
(Hab noch bisschen drumherum Code angezeigt)
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19:
| query1.Close; query1.SQL.Text := format('select geschlecht, max(punkte) as maxpkt, klasse, name, vorname from "%s" S ' + 'group by geschlecht, Klasse, name, vorname', [Table2.tablename]); query1.Open; showmessage(inttostr(query1.RecordCount));
query1.First; n := 1; repeat stringgrid1.Cells[0,n] := inttostr(n); stringgrid1.Cells[1,n] := query1.fieldbyname('maxPkt').asstring; stringgrid1.Cells[2,n] := query1.fieldbyname('Geschlecht').asstring; stringgrid1.Cells[3,n] := query1.fieldbyname('Klasse').asstring; stringgrid1.Cells[4,n] := query1.fieldbyname('Name').asstring; stringgrid1.Cells[5,n] := query1.fieldbyname('Vorname').asstring; query1.Next; inc(n); until n = query1.RecordCount+1; stringgrid1.RowCount := n; |
Nersgatt - Di 30.06.09 14:16
Du verwendest eine Agregatfunktion (MAX). Dann musst Du die anderen Felder gruppieren (GROUP BY)
D. Annies - Di 30.06.09 19:56
Hi, Nersgatt,
aber ich denke, es ist gruppiert?
Kann nochmal jemand hingucken?
Detlef
dummzeuch - Di 30.06.09 20:20
D. Annies hat folgendes geschrieben : |
Feld in order by muss im Resultat enthalten sein.
Delphi-Quelltext 1: 2: 3: 4:
| query1.SQL.Text := format('select S.geschlecht, max(S.punkte), S.klasse, S.name, S.vorname from "%s" S ' + 'where (S.Punkte > 0) '+ 'order by S.geschlecht, S.punkte, S.Klasse, S.name, S.vorname', [Table2.tablename]); |
|
In Select sind enthalten:
* geschlecht
* klasse
* name
* vorname
In Order By sind enthalten:
* geschlecht
* punkte
* klasse
* name
* vorname
Was fehlt? Punkte
Das liegt daran, dass Du fuer Punkte eine Aggregatfunktion (Max) verwendest, ohne zu gruppieren.
Folgendes sollte funktionieren (ungetestet):
SQL-Anweisung
1: 2: 3: 4: 5:
| select max(punkte) maxpunkte, geschlecht, klasse, name, vorname from xxx group by geschlecht, klasse, name, vorname having maxpunkte > 0 order by maxpunkte |
twm
D. Annies - Di 30.06.09 20:38
Funktioniert leider nicht!
Wer hat eine Idee?
Nochmal zur Sicherheit:
Es sind ca. 180 S in 6 Klassen. Die 6 besten Mä und die 6 besten Ju will ich sehen.
Also immer das beste Mä und den besten Ju pro Klasse, das sind also 12 Datensätze.
Danke, Detlef
jfheins - Mi 01.07.09 00:06
Ich hab da was :mrgreen:
Dank dir hab ich gelernt, wozu joins gut sind ^^
AAAlso: Meine Test-Tabelle:
SQL-Anweisung
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46:
| -- phpMyAdmin SQL Dump -- version 3.3.0-dev -- http://www.phpmyadmin.net -- -- Host: localhost -- Erstellungszeit: 01. Juli 2009 um 00:05 -- Server Version: 5.1.34 -- PHP-Version: 5.2.9-4
SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
-- -- Datenbank: `test` --
-- --------------------------------------------------------
-- -- Tabellenstruktur für Tabelle `meintest` --
CREATE TABLE IF NOT EXISTS `meintest` ( `id` int(11) NOT NULL AUTO_INCREMENT, `klasse` int(11) NOT NULL DEFAULT '0', `geschlecht` enum('m','w') NOT NULL DEFAULT 'm', `punkte` int(11) NOT NULL DEFAULT '0', `name` varchar(255) NOT NULL DEFAULT '', PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=13 ;
-- -- Daten für Tabelle `meintest` --
INSERT INTO `meintest` (`id`, `klasse`, `geschlecht`, `punkte`, `name`) VALUES (1, 1, 'm', 120, 'hans'), (3, 1, 'w', 110, 'sophie'), (4, 1, 'm', 104, 'klaus'), (5, 2, 'm', 124, 'hansi'), (6, 2, 'w', 30, 'lena'), (7, 2, 'w', 106, 'claudia'), (8, 2, 'm', 90, 'detlef'), (9, 2, 'w', 87, 'annemarie'), (10, 3, 'm', 80, 'hans 2'), (11, 3, 'm', 107, 'Klaus 2'), (12, 3, 'w', 96, 'Julia'); |
Und mein Statement:
SQL-Anweisung
1: 2: 3: 4: 5: 6: 7: 8: 9:
| SELECT name, geschlecht, klasse, punkte FROM ( SELECT max( punkte ) maxpunkte, geschlecht g, klasse k FROM meintest GROUP BY klasse, geschlecht ) AS a LEFT JOIN meintest ON maxpunkte = punkte AND g = geschlecht AND k = klasse |
(benötigt MySQL 5.1 oder besser)
Ergebnis:
Quelltext
1: 2: 3: 4: 5: 6: 7: 8:
| name geschlecht klasse punkte ---------------------------------------- hans m 1 120 sophie w 1 110 hansi m 2 124 claudia w 2 106 Klaus 2 m 3 107 Julia w 3 96 |
:D
Achja: Ich weis nicht obs einfacher geht, aber ganz trivial dürfte es nicht sein.
D. Annies - Mi 01.07.09 07:59
Moin, jfheins,
um die Uhrzeit noch fit: alle Achtung!
Aber ich muss noch basteln, noch bekomme ich die Fehlermeldung:
Ungültiges Schlüsselwort Symbolstring SELECT Zeilennummer 1
und das bei folgendem "Stand":
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7:
| format('SELECT name, vorname, geschlecht, klasse, punkte ' + 'FROM (SELECT max(punkte) as maxpunkte, geschlecht g, klasse k ' + 'FROM "%s" S ' + 'GROUP BY klasse, geschlecht) AS a ' + 'LEFT JOIN S ON maxpunkte = punkte ' + 'AND g = geschlecht ' + 'AND k = klasse ', [Table2.tablename]); |
Wird wohl bald gelöst sein ... :think:
bis denn, fahr jetzt erstmal zur Schule ...
Gruß, Detlef
Nersgatt - Mi 01.07.09 08:03
Welches Datenbanksystem benutzt Du? Subselects werden nicht von allen Systemen untersützt.
D. Annies - Mi 01.07.09 09:18
Hi, Nersgatt,
nun, ich nehme den SQL-Dialekt von Delphi 6.
Gibt es dafür eine Lösung?
jasocul - Mi 01.07.09 09:37
Delphi hat mit dem SQL-Dialekt nichts zu tun.
Führe den Befehl mal direkt auf der Datenbank aus. Es gibt bestimmt ein Front-End dafür.
D. Annies - Mi 01.07.09 09:40
Hi, Peter,
leider weiß ich nicht, wie das geht, aber deine zweite Aussage läßt mich ja doch hoffen.
Gruß, Detlef
jasocul - Mi 01.07.09 09:42
Welches DB-System verwendest du?
Wenn du das sagen kannst, können wir dir vermutlich auch ein kostenloses Front-End empfehlen.
D. Annies - Mi 01.07.09 09:56
Hi, Peter,
ich verwende D6 Enterprise, mit den mitgelieferten Komponenten. BDE?
Detlef
jasocul - Mi 01.07.09 10:05
Hallo Detlef,
BDE? :shock: Demnach verwendest du vermutlich Paradox. Ist zumindest die Standard-Einstellung.
Die BDE könnte dir tatsächlich in die Suppe spucken. Aber ich meine, dass bei den BDE-Versionen von Delphi ein DB-Explorer dabei war, mit dem man auch SQL-Anweisungen "direkt" machen kann. Allerdings weiß ich nicht, wo dieser Explorer versteckt ist. Das ist leider schon ziemlich lange her, dass ich das verwendet habe.
Gruß Peter
D. Annies - Mi 01.07.09 13:50
Hi, Peter, ja stimmt, es gibt einen DBExplorer.
Aber es wäre schade, wenn ich auf diese Auswertung per Query verzichten müsste; dann müsste ich wohl etwas programmieren.
Gruß, Detlef
Nersgatt - Mi 01.07.09 14:09
Wie wäre es denn damit (getestet mit FB 2.0):
SQL-Anweisung
1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| select name, punkte, geschlecht, klasse from meintest mt where punkte = (select max(punkte) from meintest mt2 where mt2.klasse = mt.klasse and mt2.geschlecht = mt.geschlecht group by klasse, geschlecht) |
Selbe Testtabelle, wie von jfheins.
BenBE - Mi 01.07.09 14:32
Hier mal ohne Sub-Selects:
SQL-Anweisung
1: 2: 3: 4: 5:
| SELECT t.klasse, t.geschlecht, t.name, t.punkte FROM meintest AS t INNER JOIN meintest AS t2 ON t.id = t2.id WHERE t.punkte = MAX(t2.punkte) GROUP BY t2.klasse, t2.geschlecht ORDER BY t.klasse, t.geschlecht |
Ungetestet, sollte aber soweit tun ...
Nersgatt - Mi 01.07.09 14:52
BenBE hat folgendes geschrieben : |
| Ungetestet, sollte aber soweit tun ... |
Sollte soweit NICHT tun. Aggregatfunktion in der Where-Klausel, da muss man HAVING benutzen.
D. Annies - Mi 01.07.09 15:19
Danke erstmal wieder, ich möchte den Tabellennamen gern variabel übergeben, aber noch Fehler zur Laufzeit: prg schmiert ab --> Taskmanager
aktuelle Version:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8:
| format('select name, punkte, geschlecht, klasse ' + 'from "%s" S ' + 'where punkte = (select ' + 'max(punkte) ' + 'from "%s" F ' + 'where F.klasse = S.klasse and ' + ' F.geschlecht = S.geschlecht ' + 'group by klasse, geschlecht)', [table2.tablename, table2.tablename]); |
Gruß, Detlef
D. Annies - Mi 01.07.09 15:48
Jetziger Stand:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7:
| format('select S.name, S.punkte, S.geschlecht, S.klasse ' + 'from "%s" S ', [table2.tablename]) + format('where punkte = (select max(punkte) ' + 'from "%s" F ', [table2.tablename]) + 'where F.klasse = S.klasse and ' + ' F.geschlecht = S.geschlecht ' + 'group by S.klasse, S.geschlecht)'; |
Meldung: Operation nicht anwendbar.
Detlef (ich sitze hier bei 34,7°C, echt)
D. Annies - Mi 01.07.09 17:04
@benny: Fehlermeldung: Merkmal nicht verfügbar. Ich habe so adaptiert:
Delphi-Quelltext
1: 2: 3: 4: 5:
| format('SELECT s.klasse, s.geschlecht, s.name, s.vorname, s.punkte ' + 'FROM "%s" S INNER JOIN "%s" T ON (s.name = t.name) and (s.vorname = t.vorname) and (s.klasse = t.klasse) ' + 'WHERE s.punkte = MAX(t.punkte) ' + 'GROUP BY s.klasse, s.geschlecht ' + 'ORDER BY s.klasse, s.geschlecht', [table2.tablename, table2.tablename]); |
Detlef
D. Annies - Mi 01.07.09 21:53
@ Peter:
Kann ich denn ein anderes FrontEnd einbinden und wenn ja, welches?
Gruß, Detlef [aufgeben is nich ] :D
Robert.Wachtel - Mi 01.07.09 22:08
Dein Frontend ist nicht das Problem, das Backend ist es.
Nimm ein vernünftiges RDBMS oder vergiss die ganzen intelligenten SQL-Konstrukte - das kann Paradox nicht.
D. Annies - Mi 01.07.09 22:14
Schade, schade!
Frage beantwortet?
Schnief, 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!