# Problem mit MySQL-Abfrage



## rtt (4. Okt 2004)

Hallo,

ich möchte aus meiner MySQL-DB den Eintrag mit der kleinsten ID auslesen lassen. Normalerweise geht das mit SQL so: 
	
	
	
	





```
SELECT MIN(id) FROM renderauftrag GROUP BY id
```

Wenn ich das ganze nun in Java einfüge, kommt die Fehlermeldung:
java.sql.SQLException: Column index out of range, 2 > 1

Wie muß ich den Select in Java schreiben, damit er es korrekt ausliest?
Vielen Dank schonmal für die Hilfe.
Gruß Robin


----------



## Bleiglanz (4. Okt 2004)

vergiss den GROUP BY? Was soll der an der Stelle?? du kannst nicht nach einer Spalte gruppieren und gleichzeitig eine Aggregatfunktion darauf loslassen!

Das Resultset bei dieser Abfrage besteht aus genau einer zeile und einer Spalte (also rs.next()...rs.getInt(1) ist schon alles)


----------



## rtt (4. Okt 2004)

es soll ja der ganze Datensatz mit der kleinsten ID angezeigt werden, nicht nur die ID selbst.

Hier mal ein auszug aus meinem code:

```
Statement stmt = connection.createStatement();
       		String sql_out = "SELECT MIN(id) FROM renderauftrag"; 
       		ResultSet rs = stmt.executeQuery(sql_out);
       		//while(rs.next()){System.out.println(rs.getInt(1));}
       		
       		while(rs.next()) 
				{  
    			System.out.print(rs.getString(1));
    			System.out.print(rs.getString(2)); 									// Ausgabe der Spalten
    			System.out.print(rs.getString(3)); 
    			System.out.print(rs.getString(4));
    			System.out.print(rs.getString(5)); 
    			System.out.print(rs.getString(6)+"\n"); 
				}
```

Gruß Robin


----------



## rtt (4. Okt 2004)

Hab das Problem gelöst.
damit gehts:

```
String sql_out = "SELECT Min(id), cmd0, cmd1, cmd2, cmdV, ip FROM renderauftrag GROUP by id";
```

Gruß Robin


----------



## rtt (4. Okt 2004)

also, das Problem scheint doch nicht gelöst zu sein. 
Bei dieser Variante, ließt er alle einträge aus.
Ich benötige aber nur einen Eintrag, nämlich den mit der kleinsten id.

Benötige nochmal eure Hilfe.
Gruß Robin


----------



## thE_29 (4. Okt 2004)

```
String sql_out = "SELECT * FROM renderauftrag where id = (SELECT MIN(id) from renderauftrag)
```


sowas geht nur mit subselects


----------



## rtt (4. Okt 2004)

normal schon, nur bringt er dann eine SQL Syntax Fehlermeldung.  ???:L


----------



## abollm (4. Okt 2004)

rtt hat gesagt.:
			
		

> Hallo,
> 
> ich möchte aus meiner MySQL-DB den Eintrag mit der kleinsten ID auslesen lassen. Normalerweise geht das mit SQL so:
> 
> ...



Also, ehrlich gesagt verstehe ich dein Problem nicht ganz. Wenn du _allein_ den kleinsten ID-Eintrag aus deiner Datenbank abfragen und anzeigen lassen willst, dann würde ich folgenden SQL-Befehl eingeben:

```
SELECT MIN(id) FROM renderauftrag
```
Wenn du alle ID-Einträge aufsteigend, beginnend mit der kleinsten Nummer, anzeigen lassen willst, schreibst du:

```
SELECT id FROM renderauftrag order by id
```

Evtl. liegt hier - je nach Problemstellung aber auch ein datenbankabhängiges Problem vor. In Oracle kann ich z.B. schreiben:

```
SELECT MIN(id) FROM renderauftrag GROUP BY id
```

Und zwar, _ohne_ Auftreten einer SQL-Fehlermeldung. Die Frage ist nur, was mir die zusätzliche GROUP BY-Klausel bringt. Im Regelfall dürfte sich in diesem Fall die Ausführung der SQL-Abfrage verlangsamen.

Sollte MySQL etwa Standard-SQL-Syntax nicht richtig ausführen?


----------



## rtt (4. Okt 2004)

wenn ich "SELECT MIN(id) FROM renderauftrag " benutze, bekomme ich nur die Zahl der kleinsten ID. 
Ich möchte aber nicht nur die kleinste ID angezeigt bekommen, sondern auch den rest der zeile.
Also ungefähr so:
id   |   cmd0  |  cmd1  | cmd2  | cmdV  |   ip  |
-----------------------------------------------------
1     |    x1     |      y1 |        z1 |      xyz |     123  |


----------



## abollm (4. Okt 2004)

rtt hat gesagt.:
			
		

> wenn ich "SELECT MIN(id) FROM renderauftrag " benutze, bekomme ich nur die Zahl der kleinsten ID.
> Ich möchte aber nicht nur die kleinste ID angezeigt bekommen, sondern auch den rest der zeile.
> Also ungefähr so:
> id   |   cmd0  |  cmd1  | cmd2  | cmdV  |   ip  |
> ...



Wo ist das Problem?

Wenn du alle Einträge auftsteigend sortiert haben willst, schreibst du folglich:

```
SELECT id, cmd0, cmd1, cmd2, cmdV, ip FROM renderauftrag order by id
```

Das ist schon alles.


----------



## thE_29 (4. Okt 2004)

abollm, du weißt nicht wirklich was er will?

hab meinen sql Befehl nur in access/oracle ausprobiert und da gehts!
habs jetzt nun auf mysql ausprobiert und da gehts nit! (sehr komisch)
würde dir empfehlen einfach 2 befehl daraus zu machen

```
String strSql1 = "SELECT MIN(id) FROM renderauftrag"; //den wert merkst du dir
String strSql2 = "SELECT * FROM renderauftrag where id = " + variable;
```

schau obs so geht!


----------



## rtt (4. Okt 2004)

@thE_29
das problem liegt darin, dass ich nicht alle zeilen ausgeben will, sondern nur eine zeile, die mit der kleinsten id.
Also wenn ich 100 Einträge (zeilen) und ich nur einen Eintrag (zeile) angezeigt bekommen möchte.


----------



## thE_29 (4. Okt 2004)

naja, mach so wie ich es geschrieben habe!

mit dem ersten befehl bekommst du die kleinste id und mit dem 2ten fragst du auf diese ab

wenn es ein primary oder unique key ist geht das!


----------



## rtt (4. Okt 2004)

äh, der vorhergehende comment ging eigentlich an abollm. sorry meinte dich nicht thE_29.
Ich werd's mal so probieren, wie du sagtest. Danke erstmal.
Gruß Robin


----------



## abollm (4. Okt 2004)

thE_29 hat gesagt.:
			
		

> abollm, du weißt nicht wirklich was er will?
> 
> hab meinen sql Befehl nur in access/oracle ausprobiert und da gehts!
> habs jetzt nun auf mysql ausprobiert und da gehts nit! (sehr komisch)
> ...



@thE_29:

Das ist aus seinem letzten Posting ja nun eindeutig klar. Aber du hast ja scon in deinem ersten Posting die Lösung dafür gegeben. Wenn diese in MySQL nicht funktioniert, liegt es offensichtlich an MySQL. Ich werde das jetzt einmal in MYSQL testen.


----------



## foobar (4. Okt 2004)

In Mysql würde ich das so machen:

```
SELECT * 
FROM renderauftrag
order by id
limit 1
```


----------



## thE_29 (4. Okt 2004)

@abollm: der zusammengehängte befehl ging net, aber extra gehn sie!
warum sie zusammengehängt net gehen, versteh i net wirklich!
aber du könntest auch foobars beitrag nehmen 
deiner war ja eigentlich auch so!

wenn man sagt order by und einfach den ersten nimmt, ist es ja eigentlich das minimum 
du müsstest ja net mal limit 1 sagen, einfach nur den ersten satz nehmen und den rest kannste knicken ..


----------



## rtt (4. Okt 2004)

@thE_29
es funktioniert, danke

ich habs so gemacht:

```
// select from DB
    		   Statement stmt = connection.createStatement();
       		String sql_id = "";
       		
       		// getting id from Select
       		String sql_out_id = "SELECT MIN(id) FROM renderauftrag";
       		ResultSet rs1 = stmt.executeQuery(sql_out_id);
       		while(rs1.next()){sql_id = rs1.getString(1);}
       		
       		// getting entry with selected id
       		String sql_out = "SELECT * FROM renderauftrag WHERE id="+sql_id;
       		System.out.println(sql_out);		
       		ResultSet rs = stmt.executeQuery(sql_out);
       		while(rs.next()) 
				{  
    			System.out.print(rs.getString(1)+"\n");
    			System.out.print(rs.getString(2)+"\n"); 									// Ausgabe der Spalten
    			System.out.print(rs.getString(3)+"\n"); 
    			System.out.print(rs.getString(4)+"\n");
    			System.out.print(rs.getString(5)+"\n"); 
    			System.out.print(rs.getString(6)+"\n"); 
				}
```

Das Problem ist, das die Einträge immer wieder gelöscht werden, ähnlich einer Warteschlange. Derjenige der schon dran war fliegt raus und der nächste rutscht nach.

Danke Jungs für eure Hilfe.
Gruß Robin


----------



## rtt (4. Okt 2004)

Hab nochmal foobar's vorschlag ausprobiert. 
Es funktioniert ebenfalls.
THX
Gruß Robin


----------



## Bleiglanz (4. Okt 2004)

du kannst auch einen self join der Tabelle mit sich selbst machen (das ist in mysql der Ersatz für subselects)


----------



## thE_29 (5. Okt 2004)

also geht in mysql kein subselect?
wußte ich gar net, na so ein schmarn


----------



## nollario (5. Okt 2004)

doch, die subselects gehen ab version 4.1!


----------



## thE_29 (5. Okt 2004)

aha!
und wo seh ich welche version ich da grad habe?


----------



## foobar (5. Okt 2004)

> du kannst auch einen self join der Tabelle mit sich selbst machen (das ist in mysql der Ersatz für subselects)


Wie kann man denn die Aggregatsfuktion in dem Selfjoin unterbringen? Ich habs zuerst auch mit einem Selfjoin probiert, hatte aber Probleme die Min-Funktion zu verwenden.


----------



## nollario (5. Okt 2004)

version:

beim mysql shell kommt sowas:


> Your MySQL connection id is 10584 to server version: 4.0.17-standard



ausserdem kannst du durch die eingabe von


```
status;
```
 (auch im mysql client)

infos über den server bekommen....


----------



## thE_29 (5. Okt 2004)

also bei version kommt ein TÜT
und status sagt
4.0.20a
also die 4.0.20a und da gehn keine subs

brauch ich also ne 4.1.xx?


----------



## Bleiglanz (5. Okt 2004)

ich machs mal aus dem Kopf

SELECT  a.id, a.wert1, MIN(b.id) -- vorne was du willst
FROM meine a, meine b -- zweimal das gleiche
WHERE a.id = b.id -- über den primärschlüssel zusammenhängen
GROUP BY b.id -- in der "Kopie" Gruppieren

bitte nicht schimpfen wenns nicht geht, sowas ist immer frickelig

mit dem self join praktisch an jede Zeile eine Kopie anhängen und dann "hinten" gruppieren


----------



## Bleiglanz (5. Okt 2004)

natürlich quatsch, echt falsch

GROUP BY b.id geht sicher nicht, jetzt muss ichs doch mal ausprobieren


----------



## Bleiglanz (5. Okt 2004)

ohne die WHERE Klausel, mit Having gehts

SELECT a.id, a.wert , MIN(b.id) 
FROM list a, list b
GROUP BY a.id, a.wert
HAVING a.id = MIN(b.id)


----------



## abollm (5. Okt 2004)

Ich sage nur: im Zweifelsfalle lieber doch ein _echtes_ RDBMS verwenden, wie z.B. Oracle. MySQL ist zwar gut, aber so richtig professionellen Ansprüchen genügt es zurzeit noch nicht.
Was nicht ist, kann aber noch werden.


----------



## thE_29 (5. Okt 2004)

naja, für den heimgebrauch reicht mysql 
außerdem isses leicht handzuhaben (meiner meinung nach)

aber es gibt sicher noch ein paar andere gratis DBs


----------



## foobar (5. Okt 2004)

@Bleiglanz Danke   Auf die Idee das ganze mit Having zu lösen, bin ich nicht gekommen. Ich hab es die ganze Zeit mit group by vergeblich versucht. 
BTW die Group-By-Klausel kann man auch weglassen, da a.id und MIN(b.id) sowieso den selben Wert haben.

```
SELECT a.id, a.wert
FROM list a, list b
HAVING a.id = MIN(b.id)
```


----------



## rtt (5. Okt 2004)

es gibt ja zum beispiel auch noch PostgreSQL
http://www.postgresql.com/

Da weiß ich aber nicht, ob da Subselects funktionieren.
Gruß Robin


----------



## semi (5. Okt 2004)

Wie wär's damit?

```
SELECT id, cmd0, cmd1, cmd2, cmdV, ip
FROM tabelle
ORDER BY id
LIMIT 1
```
bzw. für die höchste ID

```
SELECT id, cmd0, cmd1, cmd2, cmdV, ip
FROM tabelle
ORDER BY id DESC
LIMIT 1
```
Gruß,
Michael


----------



## thE_29 (6. Okt 2004)

das hatten wir schon 
und das limit1 kannste dir genausogut sparen, musst ja einfach nur das erste ergebnis rauslesen


----------



## nollario (6. Okt 2004)

limit hat auch den nachteil, dass es kein standard sql ist - sprich: wechsel db = wechsel code...


----------



## Guest (6. Okt 2004)

Ohh, sorry. Ich habe die Antwort von foobar übersehen. :autsch:
Wenn man nicht vor hat eine andere Datenbank zu verwenden, dann ist es 
die einfachste Lösung, die auch in der MySQL-Doku vorgeschlagen wird.

Gruß,
Michael


----------

