[SQL,ORACLE] Kleinstwert in View

Hallo,

ich möchte mir den Kleinstwert einer Selektion ausgeben lassen. Dabei wird jedoch nicht mit einer Basistabelle sondern mit einer View gearbeitet. Zudem sind die Tabelleninhalte alle Strings. Also z.B.:

BG A
1 100
2 200
3 300
4 400

BG= Bezugsgröße

Ich möchte jetzt zum Beispiel zunächst alle Werte für A haben, die größer 160 sind. Von dieser Ergebnismenge dann schließlich den kleinsten vorkommenden Wert. In diesem Fall also 200. Man beachte, dass es sich hier wie gesagt um Strings handelt. Das SQL-Statement zur Selektion aller Werte größer 160 sieht bei mir folgendermaßen aus:

SELECT Col_Name,Value FROM View1 WHERE
KS_Name = ‚ABCD‘ AND
Tab_Name = ‚ABCD_T1‘ AND
Col_Name = ‚A‘ AND
Value >= 160

Wie kann bzw. muss ich jetzt den Kleinstwert ermitteln mit MIN()? Ich dache es würde reichen wenn ich es so schreibe:

SELECT Col_Name,MIN(Value) FROM View1 WHERE …

Aber das reicht nicht. So funktioniert es nicht. Muss ich hier nicht auch mit TO_NUMBER() arbeiten? Bin für jede Anregung sehr dankbar! Vielen Dank.

Gruß,
Stevie

Hi Stevie,

das to_number kannst du dir sparen, das dürfte dein DBMS machen…

du muss bei allen Abfragen gruppieren, sofern dass Ergebnis, eine Spalte und eine Spalte, auf die eine zusammenfassende Funktion angewendet wird, ist.
(BSP. min, count, sum usw.)

…bei dir wäre das

SELECT Col_Name,Min(Value) FROM View1 WHERE
KS_Name = ‚ABCD‘ AND
Tab_Name = ‚ABCD_T1‘ AND
Col_Name = ‚A‘ AND
Value >= ‚160‘
group by col_name

Gruß Benjamin

Hallo Benjamin,

das to_number kannst du dir sparen, das dürfte dein DBMS
machen…

Ja stimmt. Ist auch so. Hab’s ausprobiert.

du muss bei allen Abfragen gruppieren, sofern dass Ergebnis,
eine Spalte und eine Spalte, auf die eine zusammenfassende
Funktion angewendet wird, ist.
(BSP. min, count, sum usw.)

Habe es getestet und es funktioniert. Exzellente Arbeit! Vielen Dank. Ich habe jetzt schon so viele Stunden vergeblich damit verbracht. Ich bin halt absoluter SQL-Laie, muss es aber um jeden Preis umsetzen. Vielen Dank für die prompte Hilfe!!!

Gruß,
Stevie

Hallo Benjamin,

leider habe ich mich etwas zu früh gefreut. Dein Lösungsvorschlag ist natürlich vollkommen richtig und funktioniert prima. Mein eigentliches Problem sieht allerdings mittlerweile ein klein wenig anders aus. Ich dachte ich würde mit Deinem Lösungsvorschlag alleine zurecht kommen. Fehlanzeige! Könntest Du bitte noch einmal einen Blick darauf werfen?

Meine Tabelle:

BG A B
1 100 50
2 200 60
3 300 70
4 400 80

Ich muss mit einem Vergleichswert in Spalte B gehen. Also z.B. alle Werte aus B größer 55. Hiermit erhalte ich die Bezugsgrößen BG 2,3 und 4. Mithilfe dieser Bezugsgrößen (Primärschlüssel) muss ich mir dann die Werte aus A auslesen und davon der Kleinstwert.

Mein SQL-Statement sieht bis jetzt folgendermaßen aus:

SELECT Col_Name,MIN(Value) FROM View1 WHERE
KS_Name = ‚ABCD‘ AND
Tab_Name = ‚ABCD_T1‘ AND
Col_Name = ‚A‘ AND
BG = (SELECT BG FROM View1 WHERE KS_Name = ‚ABCD‘ AND
Tab_Name = ‚ABCD_T1‘ AND Col_Name = ‚B‘ AND Value >= 55)
GROUP BY Col_Name

Was ist daran falsch? Es funktioniert so nicht. Vielen Dank!

Gruß,
Stevie

Ich muss mit einem Vergleichswert in Spalte B gehen. Also z.B.
alle Werte aus B größer 55. Hiermit erhalte ich die
Bezugsgrößen BG 2,3 und 4. Mithilfe dieser Bezugsgrößen
(Primärschlüssel) muss ich mir dann die Werte aus A auslesen
und davon der Kleinstwert.

Mein SQL-Statement sieht bis jetzt folgendermaßen aus:

SELECT Col_Name,MIN(Value) FROM View1 WHERE
KS_Name = ‚ABCD‘ AND
Tab_Name = ‚ABCD_T1‘ AND
Col_Name = ‚A‘ AND
BG = (SELECT BG FROM View1 WHERE KS_Name = ‚ABCD‘ AND
Tab_Name = ‚ABCD_T1‘ AND Col_Name = ‚B‘ AND Value >= 55)
GROUP BY Col_Name

Was ist daran falsch? Es funktioniert so nicht. Vielen Dank!

Gruß,
Stevie

Meiner Meinung nach ist daran falsch dass du viel zu kompliziert denkst…
Laut deiner Beschreibung brauchst du den Primärschlüssel gar nicht. nimm einfach meinen letzten Select, mach die kleiner-gleich Abfrage auf b, und mach das min, sowie die Gruppierung auf a.
BG, kann dir dabei egal sein, liegt doch sowieso alles in der gleichen View.

Hi Stevie,

entweder habe ich grobe Probleme, dein Datenmodell zu verstehen oder deine Statements verwirren mich restlos… Wenn es jedenfalls das ist, was ich glaube, dann sollte derjenige, der diese Db erstellt hat mindestens 20 Jahre in der DB-Designer-Hölle verbringen müssen.
Wie auch immer, ich bastel mir mal meine Beispieltabelle:

CREATE TABLE myTab (pk NUMBER(9) PRIMARY KEY, 
 colNum NUMBER(9), 
 colTxt VARCHAR2(9), 
 colTxt2 VARCHAR2(9));
INSERT INTO myTab (pk, colNum, colTxt, colTxt2)
 SELECT rownum, 
 MOD(rownum, 100), 
 TO\_CHAR(MOD(rownum, 100)), 
 TO\_CHAR(MOD(rownum, 37))
 FROM all\_objects;

Ein paar Gruppenfunktionen:

  • Der größte Wert in colNum

    SELECT MAX(colNum) FROM myTab;

  • Der größte Wert in colNum, wo colTxt größer als 50 ist

    SELECT MAX(colNum) FROM myTab WHERE TO_NUMBER(colTxt) > 50;

  • Der größte Wert in colTxt2, wo colTxt größer als 50 ist

    SELECT MAX(TO_NUMBER(colTxt2)) FROM myTab WHERE TO_NUMBER(colTxt) > 50;

  • Der größte Wert in colNum, von den Zeilen, in denen colTxt2 ein Minimum hat

    SELECT MAX(colNum) FROM myTab WHERE colTxt2 IN
    (SELECT TO_CHAR(MIN(TO_NUMBER(colTxt2))) FROM myTab);

Ich hoffe das hilft Dir erst einmal weiter. Wie schon angemerkt wurde erfolgt die Konvertierung von VARCHAR2 auf NUMBER und umgekehrt normalerweise automatisch. Allerdings liegt da auch ein kleiner Fallstrick dahinter:

DROP TABLE myTab;
CREATE TABLE myTab(c VARCHAR2 (2));
INSERT INTO myTab VALUES ('01');
INSERT INTO myTab VALUES ('1');
SELECT \* FROM myTab WHERE c=(SELECT MIN(c) FROM myTab);
SELECT \* FROM myTab WHERE c=(SELECT MIN(TO\_NUMBER(c)) FROM myTab);

Ich bin ein Verfechter der expliziten Typkonvertierung (in JEDER Programmiersprache) - das ist zwar etwas mehr Schreibarbeit, aber die zahlt sich einfach schon dadurch aus, dass der nachfolgende Programmierer sieht, dass du diesen String absichtlich als Zahl interpretiert hast, und dass dir dabei nicht etwa ein Flüchtigkeitsfehler unterlaufen ist.

Beste Grüße,
Martin