Derby/JavaDB NOT LIKE problem

mirisbowring

Bekanntes Mitglied
Guten Abend,

ich bin gerade dabei, eine Bestenliste aufzustellen.
Allerdings möchte ich es vermeiden, dass eine Person mehrfach auftaucht (wenn sie 2 sehr gute Leistungen erbracht hat, also 1. und 2. wäre).
Dazu habe ich einen SQL Befehl erstellt, der mit dem NOT Teil ein Problem hat (ohne diesen Teil funktioniert der Befehl).

Hier die Abfrage:
Java:
"SELECT NAME FROM SCHUELER WHERE SCHUELER_ID IN (SELECT SCHUELER_ID FROM MACHT WHERE DISZIPLIN_ID = " + didj + " AND WERTE = " + j9102 + " AND SCHUELER_ID NOT LIKE " + namej9101 + ") AND KLASSEN_ID IN (SELECT KLASSEN_ID FROM KLASSE WHERE KLASSENSTUFE = 910)";

wie genau kann ich dieses Problem vermeiden?
 
Ich wiederhole einmal die Problemstellung, damit du prüfen kannst, ob ich es verstanden habe:
Du willst die Teilnehmer sortiert ausgeben. Und zwar soll für jeden Teilnehme das beste Ergebnis zählen.

Dazu würde ich dir folgende Ansatz vorschlagen:
Code:
select name, max(punkte)
from <tabelle>
where <bedingung>
group by name
order by max(punkte) desc

Ich muss aber dazu sagen, dass ich vor allem Oracle verwende und nicht weiß, ob deine DB alles davon unterstützt.
 
Danke für die Rückmeldung,

Du hast es schon ganz gut erfasst...
Also ich möchte die besten 3 Plätze haben (also die Top drei aller Teilnehmer).
den ersten kann ich ja ganz leicht ermitteln, indem ich den höchsten Wert nehme.
Allerdings ist es so, dass ich die Abfrage für den 2. Platz genauso gestalten möchte, nur eben den Teilnehmer des 1. Platzes ausschließen.
Also
Code:
SELECT name
FROM Tabelle
WHERE zweitbesterwert NOT Teilnehmer von bester Wert
#

hier könnte der zweitbeste Wert auch der drittbeste sein, falls der beste Teilnehmer ersten beiden Plätze belegen würde...
 
Warum lässt du dir nicht einfach die ersten drei auf einmal ausgeben? Dann solltest du doch ein result Set bekommen über das du iterieren kannst und du hast kein weiteres Problem.
Ich stelle mir das dann etwa so vor :
Code:
Select name, max(punkte) 
From abc
Group by name
Order by place
Limit 3
Da es früh ist kann ich nichtr die Richtigkeit des obigen Codes garantieren 😉
 
Zuletzt bearbeitet:
naja das problem dabei ist ja, dass einer auch 2 Bestwerte haben kann (zur Zeit)...

Ich glaube ich ändere das Eingabesystem in der nächsten Version, sodass nur der beste Wert eines Teilnehmers gespeichert wird.

@CursedCookie,
deine Idee würde ich vermutlich in die nächste Version einbauen.
Da habe ich allerdings noch eine Frage:
Die Datenbanktabelle hat folgende Spalten:
- WerteID (auto generated)
- TeilnehmerID (mit dieser ID kann ich den Namen aus einer anderen Tabelle lesen)
- DisziplinID (damit kann ich alles zu dieser Disziplin auslesen, also welche, Geschlecht - wegen Bewertung, etc.)
- Wert (der erreichte Wert).


Bisher habe ich immer alle Werte rausgesucht für die jeweilige Disziplin ID, welche in einer Combobox angewählt war.
Die werte habe ich dann in eine ArrayList geschrieben und mit der Collection.sort Methode vom besten zum schlechtesten sortiert.
Allerdings ist dabei das Problem entstanden, dass Wenn 2 verschiedene Teilnehmer den selben Wert haben, der zweite Werte den gleichen Teilnehmer wie der erste Wert bekommt, wobei es eigentlich ein anderer ist).

Ist es möglich, auch gleich die TeilnehmerID auszulesen, und die so dem Wert zuzuordnen, dass sie auch nach dem Sort noch stimmt?

Ich hoffe ich habe mich gerade halbwegs verständlich ausgedrückt 😀
 
Zuletzt bearbeitet:
Ich nehme mal am du meinst etwas in Richtung join. Dabei verbindest du zwei Tabellen miteinander im Sinne von "nimm mir alles von den Tabellen a und b, und mach mir immer eine Zeile aus den einzelnen Zielen die in der Spalte x denselben wert haben". Funktioniert wenn du irgendwie ne Teilnehmer in oder sowas hast die du in der Disziplin speicherst. Irgendwie musst du eine Zeile aus der einen Zeile einer Zeile aus der anderen zuordnen können.
 
Ich kann die beiden indirekt zuordnen, denn es gibt eine Teilnehmer Tabelle, wo jeder eine ID bekommt, eine Disziplin Tabelle, wo jede Disziplin eine ID bekommt, und die Werte Tabelle, mit den Werte ID's.
In die Werte Tabelle werden die Teilnehmer und Disziplin ID gespeichert, denen eine Werte ID zugeordnet und zusätzlich der erreichte Wert gespeichert.

Allerdings habe ich immer noch das Problem, dass er mir bei 2 Gleichguten Teilnehmern immer den einen Namen ausgibt, anstatt beider.

Deshalb habe ich versucht, für den 2. Platz zuschreiben:
Select den Namen, wo der wert = der 2. im Array, aber Teilnehmer NOT der erste.

wobei der erste Teilnehmer im String ist...
 
Hallo

Zum Problem mit dem Query im ersten Post (ist die Frage noch relevant?):
Ist es mögliche, dass die ' um namej9101 fehlen?

Also
Java:
DISZIPLIN_ID = " + didj + " AND WERTE = " + j9102 + " AND SCHUELER_ID NOT LIKE '" + namej9101 + "') AND KLASSEN_ID IN (SELECT KLASSEN_ID FROM KLASSE WHERE KLASSENSTUFE = 910)";


Freundliche Grüsse
CptSocket
 
@CptSocket
Ja die Frage ist noch relevant 🙂

Allerdings habe ich bereits vor dem Post probiert, die ' zu setzen, was das problem allerdings nicht behoben hat.
Deshalb dachte ich, dass ich was an dem NOT grundlegend falsch mache.

hast du noch eine andere Idee?
 
Das ist das Dialogfeld, in dem mir die Exception ausgegeben wird:
http://fs5.directupload.net/images/150927/3e2mf6qo.png
(siehe Anhang)

Das ist der printstacktrace, aus dem ich im Moment nicht wirklich schlau werde...

Code:
java.sql.SQLSyntaxErrorException: No authorized routine named 'LIKE' of type 'FUNCTION' having compatible arguments was found.
    at org.apache.derby.impl.jdbc.SQLExceptionFactory40.getSQLException(Unknown Source)
    at org.apache.derby.impl.jdbc.Util.generateCsSQLException(Unknown Source)
    at org.apache.derby.impl.jdbc.TransactionResourceImpl.wrapInSQLException(Unknown Source)
    at org.apache.derby.impl.jdbc.TransactionResourceImpl.handleException(Unknown Source)
    at org.apache.derby.impl.jdbc.EmbedConnection.handleException(Unknown Source)
    at org.apache.derby.impl.jdbc.ConnectionChild.handleException(Unknown Source)
    at org.apache.derby.impl.jdbc.EmbedStatement.execute(Unknown Source)
    at org.apache.derby.impl.jdbc.EmbedStatement.executeQuery(Unknown Source)
    at datenbankgui.bestenlistepanel.jButton1ActionPerformed(bestenlistepanel.java:1079)
    at datenbankgui.bestenlistepanel.access$000(bestenlistepanel.java:26)
    at datenbankgui.bestenlistepanel$2.actionPerformed(bestenlistepanel.java:183)
    at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022)
    at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2346)
    at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
    at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
    at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
    at java.awt.Component.processMouseEvent(Component.java:6525)
    at javax.swing.JComponent.processMouseEvent(JComponent.java:3324)
    at java.awt.Component.processEvent(Component.java:6290)
    at java.awt.Container.processEvent(Container.java:2234)
    at java.awt.Component.dispatchEventImpl(Component.java:4881)
    at java.awt.Container.dispatchEventImpl(Container.java:2292)
    at java.awt.Component.dispatchEvent(Component.java:4703)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4898)
    at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4533)
    at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4462)
    at java.awt.Container.dispatchEventImpl(Container.java:2278)
    at java.awt.Window.dispatchEventImpl(Window.java:2750)
    at java.awt.Component.dispatchEvent(Component.java:4703)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
    at java.awt.EventQueue.access$500(EventQueue.java:97)
    at java.awt.EventQueue$3.run(EventQueue.java:709)
    at java.awt.EventQueue$3.run(EventQueue.java:703)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:86)
    at java.awt.EventQueue$4.run(EventQueue.java:731)
    at java.awt.EventQueue$4.run(EventQueue.java:729)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
Caused by: java.sql.SQLException: No authorized routine named 'LIKE' of type 'FUNCTION' having compatible arguments was found.
    at org.apache.derby.impl.jdbc.SQLExceptionFactory.getSQLException(Unknown Source)
    at org.apache.derby.impl.jdbc.SQLExceptionFactory40.wrapArgsForTransportAcrossDRDA(Unknown Source)
    ... 47 more
Caused by: ERROR 42884: No authorized routine named 'LIKE' of type 'FUNCTION' having compatible arguments was found.
    at org.apache.derby.iapi.error.StandardException.newException(Unknown Source)
    at org.apache.derby.impl.sql.compile.LikeEscapeOperatorNode.bindExpression(Unknown Source)
    at org.apache.derby.impl.sql.compile.UnaryOperatorNode.bindOperand(Unknown Source)
    at org.apache.derby.impl.sql.compile.UnaryLogicalOperatorNode.bindExpression(Unknown Source)
    at org.apache.derby.impl.sql.compile.BinaryOperatorNode.bindExpression(Unknown Source)
    at org.apache.derby.impl.sql.compile.BinaryLogicalOperatorNode.bindExpression(Unknown Source)
    at org.apache.derby.impl.sql.compile.AndNode.bindExpression(Unknown Source)
    at org.apache.derby.impl.sql.compile.SelectNode.bindExpressions(Unknown Source)
    at org.apache.derby.impl.sql.compile.SubqueryNode.bindExpression(Unknown Source)
    at org.apache.derby.impl.sql.compile.BinaryOperatorNode.bindExpression(Unknown Source)
    at org.apache.derby.impl.sql.compile.BinaryLogicalOperatorNode.bindExpression(Unknown Source)
    at org.apache.derby.impl.sql.compile.AndNode.bindExpression(Unknown Source)
    at org.apache.derby.impl.sql.compile.SelectNode.bindExpressions(Unknown Source)
    at org.apache.derby.impl.sql.compile.DMLStatementNode.bindExpressions(Unknown Source)
    at org.apache.derby.impl.sql.compile.DMLStatementNode.bind(Unknown Source)
    at org.apache.derby.impl.sql.compile.CursorNode.bindStatement(Unknown Source)
    at org.apache.derby.impl.sql.GenericStatement.prepMinion(Unknown Source)
    at org.apache.derby.impl.sql.GenericStatement.prepare(Unknown Source)
    at org.apache.derby.impl.sql.conn.GenericLanguageConnectionContext.prepareInternalStatement(Unknown Source)
    ... 41 more
 

Anhänge

  • error1.PNG
    error1.PNG
    8,3 KB · Aufrufe: 24
Mir ist nicht klar, was dir bei meiner Lösung fehlt.

Die Abfrage liefert dir eine sortierte Liste von Teilnehmern und dem jeweils höchsten Punktewert des Teilnehmers.
Sortiert wird nach dem jeweils höchsten Wert des jeweiligen Teilnehmers. Die Sortierrichtung ist absteigend.
Du kannst bei der Bedingung ein beliebiges Filterkriterium einsetzen. Beispielsweise kann du nur eine bestimmte Disziplin auswählen.

Du kannst das Ergebnis dann Satz für Satz aus der Datenbank einlesen und in einem Array ablegen. Dann kannst du auf den ersten, zweiten oder irgendeinen Platz zugreifen.
 
Mir ist nicht klar, was dir bei meiner Lösung fehlt.

Die Abfrage liefert dir eine sortierte Liste von Teilnehmern und dem jeweils höchsten Punktewert des Teilnehmers.
Sortiert wird nach dem jeweils höchsten Wert des jeweiligen Teilnehmers. Die Sortierrichtung ist absteigend.
Du kannst bei der Bedingung ein beliebiges Filterkriterium einsetzen. Beispielsweise kann du nur eine bestimmte Disziplin auswählen.

Du kannst das Ergebnis dann Satz für Satz aus der Datenbank einlesen und in einem Array ablegen. Dann kannst du auf den ersten, zweiten oder irgendeinen Platz zugreifen.
Danke 😀
Ich habe deine Idee erst falsch umgesetzt gehabt, denn ich habe (weil es im Moment Schulstoff ist, und ich es üben wollte, die Datenbank in die dritte Normalform gebracht). Dabei habe ich ganz vergessen, eine spezifische Abfrage zu machen, bezüglich der Trennung von 2 Gruppen.

Jetzt läuft die Software auch schneller und der Code ist kürzer, als vorher.

Gibt nen Däumchen ;D

BTW: ich arbeite nur sehr selten mit group, weil ich das damals nicht verstanden hatte^^
 
Was mir gerade auffällt: SCHUELER_ID ist ein numerischer Wert, richtig? LIKE funktioniert nur mit Zeichenketten, nicht mit anderen Typen wie Zahlen oder Datumswerten.
Kannst du das Like durch = oder ähnlich ersetzen?


Freundliche Grüsse
CptSocket
 
Man kann in SQL Statements auch (je nach Datenbank) Funktionen Aufrufen: Damit könnte man zum Beispiel ein Datum in einen String umwandeln und auch mit LIKE Abfragen (analog dazu Zahlen)
 
Was mir gerade auffällt: SCHUELER_ID ist ein numerischer Wert, richtig? LIKE funktioniert nur mit Zeichenketten, nicht mit anderen Typen wie Zahlen oder Datumswerten.
Kannst du das Like durch = oder ähnlich ersetzen?


Freundliche Grüsse
CptSocket
Achso, dass wusste ich nicht. (erklärt dann auch die Fehlermeldung)

Man kann in SQL Statements auch (je nach Datenbank) Funktionen Aufrufen: Damit könnte man zum Beispiel ein Datum in einen String umwandeln und auch mit LIKE Abfragen (analog dazu Zahlen)

Das werde ich mir im Hinterkopf behalten.
Ich wollte de Code halt nur möglichst kurz halten.

Letztendlich habe ich Dompteurs Ansatz verwendet, was genau das ist, was ich wollte (nur etwas kürzer).

Aber danke, dass Ihr mir die Fehlermeldung noch erklärt habt.
 

Neue Themen


Zurück
Oben