Problem mit Subquery

Hallo SQL-Profis,

da ich ein Neuling in dieser Materie bin, hoffe ich auf Hilfe von euch.
Ich habe als Zwischenschritt ein View erstellt, Aend_str sieht so aus:
StrNr / Str / Aend_Str
1 / 00 / 10
2 / 01 / 20
3 / 02 / 30
4 / 03 / 40
5 / 04 / 50

die vorhandene Tabelle Aend_kat sieht so aus:
Kartennr / Kbez / Von / Bis
1 / 0-10 / 0 / 10
2 / 11-20 / 11 / 20
3 / 21-30 / 21 / 30
4 / 31-40 / 31 / 40
5 / 41-50 / 41 / 50

Das Ziel ist nun diese zu verknüpfen, dass diese Tabelle (oder auch als View) entsteht:
Strnr / Str / Aend_str / Kbez
1 / 00 / 10 / 0-10
2 / 01 / 20 / 11-20
3 / 02 / 30 / 21-30
4 / 03 / 40 / 31-40
5 / 04 / 50 / 41-50

Ich will quasi, dass der Wert bei Aend_str der entsprechenden Kategorie aus Kbez zugeordnet wird.

Es muss wohl irgendwie über eine Unterabfrage funktionieren, aber ich weiß nicht wie.
Ich wäre sehr dankbar, wenn jemand eine Idee hat.
Ich arbeite mit Watcom SQL.

Gruß.

So?

test=*# select * from t1;
 strnr | str | aend_str
-------+-----+----------
 1     | 00  | 10
 2     | 01  | 20
 3     | 02  | 30
 4     | 03  | 40
 5     | 04  | 50
(5 rows)

test=*# select * from t2;
 kartennr | kbez  | von | bis
----------+-------+-----+-----
 1        | 0-10  |   0 |  10
 2        | 11-20 |  11 |  20
 3        | 21-30 |  21 |  30
 4        | 31-40 |  31 |  40
 5        | 41-50 |  41 |  50
(5 rows)

test=*# select t1.strnr, t1.str, t1.aend_str, t2.kbez from t1 left join t2 on (t1.strnr=t2.kartennr);
 strnr | str | aend_str | kbez
-------+-----+----------+-------
 1     | 00  | 10       | 0-10
 2     | 01  | 20       | 11-20
 3     | 02  | 30       | 21-30
 4     | 03  | 40       | 31-40
 5     | 04  | 50       | 41-50
(5 rows)



Es muss wohl irgendwie über eine Unterabfrage funktionieren, aber ich weiß nicht wie.

Nein, Du suchst einen JOIN. Einfachstes Handwerkszeug bei SQL.

Ich wäre sehr dankbar, wenn jemand eine Idee hat.

Bitte.

Ich arbeite mit Watcom SQL.

Das ist sicher heilbar.


Andreas

hallo akretschmer,

vielen Dank für Deine schnelle Antwort, aber das ist nicht so ganz das richtige zu meinem Problem.
Die strnr hat nix mit der kartennr zu tun. Es ist nur ein Auszug aus den Tabellen. Strnr hat 32 Zeilen und Kartenr hat 20 Zeilen.
Es gibt keine übereinstimmenden Spalten.
Ich habe in aend_str 32 verschiedene Werte , die dann einer kbez aus Tabelle Aend_kat per Abfrage zugeordnet werden soll. Die Werte von aend_str liegen auch nicht so sortiert vor, wie in meinem Beispiel. Sondern lauten mal 5, 32, 8, 89, 51 usw.:
StrNr / Str / Aend_Str
1 / 00 / 5
2 / 01 / 32
3 / 02 / 8
4 / 03 / 89
5 / 04 / 51


Das Ergebnis müsste dann so aussehen:
Strnr / Str / Aend_str / Kbez
1 / 00 / 5 / 0-10
2 / 01 / 32 / 31-40
3 / 02 / 8 / 0-10
4 / 03 / 89 / 81-90
5 / 04 / 51 / 51-60

Es muss irgendwie über eine Subquery funtkionieren.

Vielleicht hast du ja noch eine andere Idee.

Gruß, saband

Mag sein, daß ich Dein Promlem nicht verstehe, aber:

test=*# select * from t1;
 strnr | str | aend_str
-------+-----+----------
 1     | 00  | 5
 2     | 01  | 32
 3     | 02  | 8
 4     | 03  | 89
 5     | 04  | 31
(5 rows)

test=*# select t1.strnr, t1.str, t1.aend_str, t2.kbez from t1 left join t2 on (t1.strnr=t2.kartennr);
 strnr | str | aend_str | kbez
-------+-----+----------+-------
 1     | 00  | 5        | 0-10
 2     | 01  | 32       | 11-20
 3     | 02  | 8        | 21-30
 4     | 03  | 89       | 31-40
 5     | 04  | 31       | 41-50
(5 rows)

Selbes Select wie erst, nur mit den nun genannten Daten.


Andreas

Problem leider nicht verstanden. du siehst ja jetzt, dass die Ergebnisse in kbez der Abfrage falsch sind. Bei 32 müsste 31-40 stehen, bei 8 müsste 0-10 stehen usw.
test=*# select * from t1;
strnr | str | aend_str
-------±----±---------
1 | 00 | 5
2 | 01 | 32
3 | 02 | 8
4 | 03 | 89
5 | 04 | 31
(5 rows)

test=*# select t1.strnr, t1.str, t1.aend_str, t2.kbez from t1 left join t2 on (t1.strnr=t2.kartennr);
strnr | str | aend_str | kbez
-------±----±---------±------
1 | 00 | 5 | 0-10
2 | 01 | 32 | 11-20
3 | 02 | 8 | 21-30
4 | 03 | 89 | 31-40
5 | 04 | 31 | 41-50
(5 rows)

Daher bringt ein Join nichts.
Schade.

Saband

Ach so. Okay. Du hast, vorsichtig formuliert, ein eigenartiges Datenmodell. Die Verbindung zwischen den Tabellen, die habe ich erst flasch verstanden. Du willst also Äpfel mit Kürbissen, ähm, Zahlen mit Texten vergleichen, wobei die Texte wiederum aus Zahlenkombinationen bestehen. Da muß man also etwas tiefer in die Trickkiste greifen.

Laß mich mal an einem Beispiel eine mögliche Lösung demonstrieren:

test=*# select * from t1;
 i
----
  1
 15
 25
(3 Zeilen)

Zeit: 0,326 ms
test=*# select * from t2;
   t
-------
 1-10
 11-20
 21-30
(3 Zeilen)

Zeit: 0,332 ms
test=*# select t1.*, t2.* from t1 left join t2 on ((t1.i >= regexp_replace(t2.t,'-.*','')::int) and (t1.i <= (regexp_replace(t2.t,'^.*-','')::int)));
 i  |   t
----+-------
  1 | 1-10
 15 | 11-20
 25 | 21-30
(3 Zeilen)

Fakt ist, Du suchst weiterhin nach einem Join. Bin ich mir recht sicher. Fakt ist auch, Du hast kein PostgreSQL. Meine Lösung wird daher so bei Dir wohl nicht funktionieren. Bin ich mir auch relativ sicher.


Andreas

Nachtrag:

ich hab das nun mal mit deinen Daten/Tabellen gemacht (ich hatte gestern abend keine Lust, das noch mal nachzubauen)

test=# select t1.strnr, t1.str, t1.aend_str, t2.kbez from t1 left join t2 on ((t1.aend_str::int >= regexp_replace(t2.kbez,'-.*','')::int) and (t1.aend_str::int <= (regexp_replace(t2.kbez,'^.*-','')::int)));
 strnr | str | aend_str | kbez
-------+-----+----------+-------
 1     | 00  | 5        | 0-10
 2     | 01  | 32       | 31-40
 3     | 02  | 8        | 0-10
 4     | 03  | 89       |
 5     | 04  | 31       | 31-40
(5 rows)

Schön ist was anderes…

Andreas

Örgs! Und performant wird das schon lange nicht!

Du solltest dringend über ein anderes Datenmodell nachdenken.

Er hat doch aber die Tabelle

create table t2(
kartennr serial not null,
kbez varchar(10),
von number,
bis number);
insert into t2(kzbez, von, bis) values ('0-10', 0, 10);
insert into t2(kzbez, von, bis) values ('11-20', 11, 20);
insert into t2(kzbez, von, bis) values ('21-30', 21, 30);
insert into t2(kzbez, von, bis) values ('31-40', 31, 40);
insert into t2(kzbez, von, bis) values ('41-50', 41, 50);

Damit sollte der Select doch in folgendes wandelbar sein

select t1.strnr, t1.str, t1.aend_str, t2.kbez
from t1 left join t2 on t1.aend_str between t2.von and t2.bis;

oder meinetwegen auch

select t1.strnr, t1.str, t1.aend_str, t2.kbez
from t1 left join t2 on t1.aend_str >= t2.von and t1.aend_str <= t2.bis;