# Subselect Abfrage



## Tobber (10. Mai 2006)

Hi Leute,

habe folgendes Problem:
Ich habe eine Tabelle "warehouse" die aus dem Primärschlüssel id, no, pres, pack besteht.
Die restlichen Spalten heißen glep, glepuc, fix, ....

Jetzt will ich eine Abfrage machen, die für die Spalten id und no den kleinsten glep ausgeben unabhängig von pres und pack. 

Meine Anfangsversuche sehen so aus:

```
select w1.id, w1.no, w1.pres, w1.pack, w1.glep, w1.glepuc 
from warehouse as w1, (select id, no, min(glep) glep from warehouse 
group by id, no)  as w2 where w1.no = '071593034' 
and w1.id = w2.id and w1.no = w2.no
```

Ich habe diese Einschränkung "w1.no = '071593034' " nur eingesetzt, damit nicht die ganzen Datensätze angezeigt werden. Am Ende soll das SQL-Statement auf die gesamte Tabelle losgelassen werden.

Jedenfalls kommt bei diesem SQL-Statement folgendes heraus:

```
id          no                  pres         pack         glep         glepuc
1          071593034       99              1              46,2         1
1          071593034       0                1              46,2         1
2          071593034       99              1              46,2         1
2          071593034       0                1              46,2         1
```

Eigentlich sollen nur 2 Zeilen angezeigt werden. Jedenfalls eine mit der "id = 1" und "no = 071593034" und eine mit der "id = 2" und "no = 071593034". Es ist egal welcher "pres" oder welcher "pack" angezeigt wird.

Wisst ihr zufällig eine Lösung? Ich hoffe ihr könnt mir helfen, sitze schon eine ganze Woche an dem SQL-Statement und komme einfach nicht weiter.

Gruß + Danke Tobber


----------



## bn (10. Mai 2006)

Hallo,

wenn ich dich richtig verstanden habe, möchtest zu einer jeden "no" und jeder "id" den niedrigesten "glep" auswerten.
Dafür würdest du im Grunde kein Subselect benötigen.

```
SELECT id, no, MIN(glep) FROM warehouse
GROUP by no, id
```

Diese Abfrage sollte das gewünschte Ergebnis erzielen.

Viele Grüße
Robert


----------



## Tobber (10. Mai 2006)

Hi,

diese Lösung hatte ich auch, aber in der Ausgabe muss pres und pack stehen. Und wenn man dann ein group by macht werden wieder alle 4 Zeilen ausgegeben wie oben erwähnt.

Vielleicht habt ihr noch eine andere Lösung. Meiner Meinung nach komme ich um ein subselect nicht herum, aber ihr könnt mich gerne eines besseren belehren.

Gruß + Danke Tobber


----------



## bn (10. Mai 2006)

Du hast geschrieben:


> Es ist egal welcher "pres" oder welcher "pack" angezeigt wird.



Dann ergänze einfach die Abfrage mit diesen beiden Felder und fertig.

Viele Grüße
Robert


----------



## Tobber (10. Mai 2006)

```
id          no                  pres         pack         glep         glepuc         NR:
1          071593034       99              1              46,2         1              1
1          071593034       0                1              46,2         1              2
2          071593034       99              1              46,2         1              3
2          071593034       0                1              46,2         1              4
```

Ich habe mich falsch ausgedrückt. Pack und glep müssen in der Ausgabe stehen. Aber es ist egal ob Zeile (NR 1) oder Zeile (NR 2) ausgegeben wird. Desweiteren ist egal ob Zeile (NR 3) oder Zeile (NR 4) ausgegeben werden muss. Aber jeweils eine Zeile mit der "id = 1" und "no = 017593034" und "id = 2" und "no = 071593034" muss ausgegeben werden.

Gruß Tobber


----------



## bn (10. Mai 2006)

Ok du hast dich in der Tat etwas umständlich ausgedrückt 

```
SELECT *
FROM warehouse AS a
WHERE (
	SELECT glep
	FROM warehouse AS b
	WHERE b.id = a.id
	AND b.no = b.no
	ORDER BY b.glep ASC
	LIMIT 1
) = a.glep
GROUP BY a.no, a.id, a.glep
```

Doch mit Subselect 

Robert


----------



## Tobber (10. Mai 2006)

bloddy newbie hat gesagt.:
			
		

> Ok du hast dich in der Tat etwas umständlich ausgedrückt
> 
> ```
> SELECT *
> ...




Hi,

habe es gerade ausprobiert. Kommt leider ein Fehler:

1. Bei "and b.no = b.no" hast du dich verschrieben. Ich glaube es muss "and b.no = a.no" heißen

2. Wenn ich das SQL-Statement ausführe, kommt als Fehlermeldung:

"[Red Brick][ODBC Driver][Warehouse]**ERROR** [87] Invalid syntax '...AND b.no = a.no <==> ORDER'.

Ich glaube das mit dem Order by funkt irgendwie nicht. Muss vielleicht ein group by hin?

Gruß Tobber


----------



## bn (10. Mai 2006)

Oh ich bin von MySQL (um welches DB System gehts eigentlich?) ausgegangen und hatte mich verschrieben.

Versuche es mal mit MIN() statt diesem ORDER BY - LIMIT Zeug:

```
SELECT *
FROM warehouse AS a
WHERE (
SELECT MIN( glep )
FROM warehouse AS b
WHERE b.id = a.id
AND b.no = a.no
) = a.glep
GROUP BY a.no, a.id, a.glep
```


----------



## Tobber (10. Mai 2006)

Ich benutze Informix von IBM.

Leider bekomme ich immer noch einen Fehler wenn ich folgendes Kommando schreibe:


```
SELECT *
FROM warehouse AS a
WHERE (
SELECT MIN( b.glep )
FROM warehouse AS b
WHERE b.id = a.id
AND b.no = a.no
) = a.glep
and a.no = '071593034'
roup by a.no, a.id, a.glep
```

Die Fehlermeldung lautet:

[Red Brick][ODBC Driver][Warehouse]** ERROR ** (39) When GROUP BY is present, the column in the select list, ORDER BY, HAVING, or WHEN condition must be a grouping column, aggregation function argument, or literal value.

Desweiteren muss beachtet werden, dass man am Anfang kein * machen darf, weil nur id, no, pres, pack, glep und glepuc ausggeeben werden darf.

Habt ihr noch eine Idee?

Gruß Tobber


----------



## bn (10. Mai 2006)

Die Fehlermeldung besagt, dass du alle zu selektierenden Spalten  (also id, no, pres, pack, glep und glepuc) in dem GROUP Block unterbringen mußt. Die Spalten innerhalb der WHERE Klausel sind bereits enthalten.


----------



## Tobber (10. Mai 2006)

Stimmt du hast Recht, die Fehlermeldung hatte ich schon mal.
Aber leider passt das SQL-Statement immer noch nicht.

```
SELECT a.id, a.no, a.prese, a.pack, a.glep, a.glepuc
FROM warehouse AS a WHERE ( SELECT MIN( b.glep )
FROM warehouse AS b WHERE b.id = a.id
AND b.no = a.no ) = a.glep and a.no = '071593034'
group by a.no, a.id, a.glep, a.glepuc, a.pres, a.pack
```

Und als Ergebnis kommt, das gleiche wie ich am Anfang gepostet habe, raus:


```
id          no                  pres         pack         glep         glepuc
1          071593034       99              1              46,2         1
1          071593034       0                1              46,2         1
2          071593034       99              1              46,2         1
2          071593034       0                1              46,2         1
```

Es dürfen aber nur 2 der Zeilen, wie oben beschrieben ausgegeben werden.

Mir ist gerade eine Idee gekommen:

```
SELECT a.id, a.no, MIN(a.pres) AS pres, a.pack,
( SELECT MIN( b.glep ) FROM warehouse AS b WHERE b.id = a.id
AND b.no = a.no group by b.glep, b.no, b.id
) AS glep, a.glepuc from warehouse AS a 
GROUP BY a.id, a.no, a.packa, a.glep, a.glepuc
HAVING a.no = '071593034'
```

Jetzt werden nur noch 2 Zeilen angezeigt, aber wenn ich die HAVING Anweisung entferne kommt die Fehlermeldung:
[Red Brick][ODBC Driver][Warehouse]** ERROR ** (58) Subquery returned more than one row.


Hast du noch eine andere Idee bloddy newbie.

Gruß Tobber


----------

