SQL Oracle SQL - Mehrere Ergebnise zu einer Zeile Zusammenfassen

Blubberbernd

Cadet 4th Year
Registriert
Juli 2009
Beiträge
94
Hallo,

ich bin ein ziemlicher Anfänger in SQL und habe ein Problem bei dem ich nicht weiterkomme.

Ich habe eine Tabelle in der es 3 Spalten gibt :

1. Spalte : Translationcode
2. Spalte : Übersetzungstext
3. Spalte : Language-Kürzel


Die Sittuation ist Folgende:

Der Translationcode ist ein beliebiger String, dieser wird je nach gewählter Sprache im Programm übersetzt und als Übersetzungstext angezeigt.
Das Languagekürzel identifiziert die gewählte Sprache.

Es gibt immer nur 2 aktive Sprachen:

1. Englisch mit dem Kürzel 'E'
2. eine belibige andere mit einem belibigen Kürzel (z.B: 'D' für Deutsch)


Ich möchte nun eine SQL-Abfrage starten, bei der ich 3 Spalten erhalte:

Zum einen möchte ich alle Translationcodes haben die schon mit der Sprache Englisch und einer weiteren eingetragen sind.

Zu jedem gefundenem Translationcode in der Spalte 1 soll nun in der 2. Spalte der englische Übersetzungstext gefunden werden, existiert dieser nicht, so soll das Feld mit 'null' gefüllt werden. Die dritte Spalte enthält analog zur 2. den einen weiteren beliebigen Übersetzungstext. Ist keiner vorhanden, so soll auch in diesem Fall 'null' eingetragen werden.

Die Daten in der Tabelle sehen so aus

(Die Punkte dienen nur der besseren Übersichtlichkeit)

Transcode . . . . | . . . Übersetzungstext . | . . . Languagekürzel
--------------------------------------------------------------------------------
HALLO . . . . . . .| . . . . . . . .hello . . . . . . .| . . . . . . . .E

OEFFNEN . . . . . | . . . . . . . öffnen . . . . . . | . . . . . . . D

SCHLIEßEN . . . .| . . . . . . . close . . . . . . . | . . . . . . . E

SCHLIEßEN . . . .| . . . . . . schließen . . . . .| . . . . . . . D



Das Ergebnis soll so aussehen


Transcode . . . . | . . . Englisch . | . . . Deutsch
--------------------------------------------------------

HALLO . . . . . . . | . . . . hello . . . | . . . . null

OEFFNEN . . . . . | . . . . null . . . . | . . . öffnen

SCHLIEßEN . . . .| . . . .close . . . .| . . schließen



Ich hab keine Ahnung wie die Richtige Abfrage Lautet, das einzige was ich Hinbekommen habe war Sowas wie :


Select a.Transcode ,

(Select b.text from Tabellenname b where b.value = a.value and b.language = 'E'),

(Select c.text from Tabellenname c where c.value = a.value and b.language = 'D')

from Tabellenname a

where a.Language='E' or a.Language ='D'


oder so ähnlich,

da kommt aber nur sowas raus

Transcode . . . . | . . . Englisch . | . . . Deutsch
--------------------------------------------------------

HALLO . . . . . . . | . . . . hello . . . | . . . . null

OEFFNEN . . . . . | . . . . null . . . . | . . . öffnen

SCHLIEßEN . . . .| . . . .close . . . | . . . . null

SCHLIEßEN . . . .| . . . . null . . . . | . . schließen


wie kann ich nun die Zeile mit dem Schließen wie oben gezeigt zusammenfassen?
Danke schonmal für alle Posts!


Ein Arbeitskollege meinte man könnte da was mit 'decode' ausprbieren, brachte mich aber auch nicht zum Ziel.
Muss ja nicht stimmen, aber vllt fällt Jemand damit ja auch ne Lösung ein.
 
Zuletzt bearbeitet:
Darf man fragen, wieso du eine Tabelle in der Form erstellst?
Ich hätte einfach eine Tabelle mit ID als PK und Englisch, Deutsch, Schwedisch .. usw erstellt..
oder hat "Transcode" einen speziellen Nutzen für dich ?
 
Zuletzt bearbeitet:
Hallo ExtiQ,

leider wurde die Tabelle nicht von mir erstellt und muss als Vorgabe hingenommen werden.
Sie wurde von einem Drittanbieter erstellt.

Der Translationcode und das Languagekürzel bilden dabei den Zusammengesetzten Primärschlüssel.

Desweiteren gibt es noch eine Tabelle die in den Primärschlüssel einfließt, diese ist aber an der Stelle unerheblich, da es keine Informationen gibt worauf die 3. Schlüsselspalte basiert und es lässt sich auch nichts anhand der Werte schlussfolgern.

Und ja Transcode hat einen speziellen nutzen für mich, in c# sind genau diese Texte als propperty an verschiedene Objecte gebunden. Stellt man nun zur Laufzeit die Sprache um, so wird anhand dieser Property und dem Kürzel der ausgewählten Sprache der Überzetzungstext dynamisch z.B. auf einem Button oder Label angezeigt.
 
Wenn ich das jetzt richtig verstehe willst du vom Transcode ausgehend die Übersetzung in den 2 Sprachen haben:

Code:
Select a.Transcode ,
(Select b.text from Tabellenname b where [B]b.Transcode = a.Transcode[/B] and b.language = 'E'),
(Select c.text from Tabellenname c where [B]c.Transcode = a.Transcode[/B] and b.language = 'D')
from [B](select distinct Transcode from Tabellenname where a.Language='E' or a.Language ='D')[/B] a

Denke aber das es nicht unbedingt die performanteste Variante wäre.

BTW: Keine Ahnung was die Spalte "value" in deinem Select bedeutet...
 
Zuletzt bearbeitet:
@Rossibaer: Dein Statement funktioniert zwar, aber warum das dritte Subselect? Das geht viel einfacher:
Code:
SELECT DISTINCT a.transcode AS 'Transcode',
       (SELECT b.text FROM tabellenname b WHERE b.transcode = a.transcode AND b.language = 'D') AS 'Deutsch',
       (SELECT c.text FROM tabellenname c WHERE c.transcode = a.transcode AND c.language = 'E') AS 'Englisch'
  FROM tabellenname AS a
 
@Cobinja: Das hatte ich mir auch am Anfang gedacht, aber wenn ich mich jetzt nicht wirklich arg täusche dann wirkt sich das distinct sowohl auf transcode als auch auf die 2 Subselects in der Spaltenauflistung aus. Das könnte vermutlich zu einem falschen Ergebnis führen. Hab aber gerade keine Oracle DB zur Hand, wo ich das mal durchspielen konnte. Sei es wie es sei, ich wollte mit meinem Select "nur" auf Nummer sicher gehen.

Blubberbernd kann ja mal beide Varianten prüfen und schauen welche Variante am ehesten seine Anforderungen erfüllt.

PS: Bei Cobinjas Lösung muss noch die WHERE Bedingung des Hauptselects ergänzt werden, da sonst alle Sprachkürzel (D, E, A, B, C ...) durchgeackert werden.
 
Zuletzt bearbeitet:
@ALL

Endlich habe ich eine Lösung zu meinem Problem gefunden.
Das Problem war, dass der Transcode und das languagekürzel mehrfach mit dem selben wert vorkommen können, ich erwähnte ja das es eine weitere Spalte zur Schlüsselbildung gibt. Wenn man die nicht mit einbezieht meckert er rum, das beim select mit Language 'E' mehrere einträge gefunden werden, das ist natürlich nicht zulässig.

@Rossibaer:

Das mit dem Hauptselect und der where Bedingung ist mir auch gerade aufgefallen und ich hab das bei mir ergänzt.


Meine vorläufige Lösung lautet:

1. Select Transcode,
2. decode(prim_language , null, prim_language2, prim_language) as PRIM_LANG,
3. decode(sec_language, null, sec_language2, sec_language) as SEC_LANG
4. from
5. (
6. . . . . . select distinct a.Transcode,
7. . . . . . (select text from Tabellenname where group_id='1' and Transcode= a.Transcode) as prim_language,
8. . . . . . (select text from Tabellenname where and group_id='2' lang='D' and Transcode= a.Transcode) as sec_language,
9. . . . . . (select text from Tabellenname where group_id='ZT' and Transcode= a.Transcodeand lang='E') as prim_language2,
10. . . . . . (select text from Tabellenname where group_id=ZT' and Transcode= a.Transcodeand lang='D') as sec_language2
11. . . . . . from
12. . . . . . Tabellenname a where a.lang='E' or a.lang ='D' order by Transcode asc
13. )


Zuerst Selecte ich die Tabelle vor um später davon weiter zu selecten (Zeile 6 -12)

Dabei ist bei 7 zu beachten, dass nicht nur nach der language selected werden kann, da diese mehrere einträge enthält bei gleichem Translationcode, hingegen aber der Schlüssel group_id untrennbar mit der Sprache Englisch verknüpft zu sein scheint.

In der Zeile 8 muss auf die Language und auf die group_id selectet werden, da die group_id='2' für die 2. Sprache steht und man noch mit der Language sagen muss welche.

In Zeile 9 und 10 selecte ich dann die möglichen Einträge zu beiden Languages die jeweil unter ein und der selben group_id stehen können, da sich der Primärschlüssel ja aus 3 Teilen zusammensetzt (group_id, Translationcode, language)

damit ergibt sich dann eine Vorselektierte Tabelle, die alle Translationcodes enthält der beiden gewünschten Sprachen mit 4 zusätzlichen Spalten:

1. Spalte Translationcode
2. Spalte Alle Texte in Englisch auf Basis der group_id '1'
3. Spalte alle Texte auf Deutsch auf Basis der group_id '2'
4. Spalte alle Texte auf englisch der Basis group_id 'ZT'
5. Spalte alle Texte auf Deutsch der Basis group_id 'ZT'

Bei Werten die nicht vorhanden sind steht null in diesen Feldern
mit decode stelle ich diese dann zusammen a la (if , wert, then, else).

Es kommt zumindest das gewünschte Ergebnis raus, allerdings frage ich mich, ob man die Abfrage logisch zusammenfassen kann um diese zu verkürzen?

Danke schonmal an euch beide für die Vorschläge die nun Teil der Lösung sind!


PS.: Bitte entschuldigt die katastrophale Rechtschreibung
 
Ich glaub da hat sich bei deiner Lösung noch ein Tipfehler eingeschlichen. Das fettmarkierte "AND" in Zeile 8 ist da fehl am Platz:

Code:
Select Transcode,
decode(prim_language , null, prim_language2, prim_language) as PRIM_LANG,
decode(sec_language, null, sec_language2, sec_language) as SEC_LANG
from
(
select distinct a.Transcode,
(select text from Tabellenname where group_id='1' and Transcode= a.Transcode) as prim_language,
(select text from Tabellenname where [B]and[/B] group_id='2' lang='D' and Transcode= a.Transcode) as sec_language,
(select text from Tabellenname where group_id='ZT' and Transcode= a.Transcodeand lang='E') as prim_language2,
(select text from Tabellenname where group_id=ZT' and Transcode= a.Transcodeand lang='D') as sec_language2
from Tabellenname a where a.lang='E' or a.lang ='D' order by Transcode asc
)
 
@rossibaer:

jupp das ist mir da wohl verrutscht, aber ansonsten passts eigentlich. ist sowas noch weiter zusammenfassbar, oder sollte mans so lassen, ist ja denke ich auch relativ übersichtlich.

Welche performenceunterschiede können sich denn so bei SQL-Abfragen ergeben?
Oder kann man das vernachlässigen?
 
Rossibaer schrieb:
...aber wenn ich mich jetzt nicht wirklich arg täusche dann wirkt sich das distinct sowohl auf transcode als auch auf die 2 Subselects in der Spaltenauflistung aus. Das könnte vermutlich zu einem falschen Ergebnis führen.
Das DISTINCT wirkt sich auf alle Ergenbisspalten aus, das ist richtig. Allerdings werden die Ergebnisspalten sie nicht einzeln behandelt, sondern es wird die komplette Ergebniszeile DISTINCTed, so ähnlich, als gäbe es auf dem Abfrageergebnis einen PK, der sich über alle Spalten erstreckt.
 
@Blubberbernd:
Optimierungsmaßnahmen sind der Anfang allen Übels ;) Also wenn die Abfrage ok ist und auch nicht allzu lange braucht um angezeigt zu werden, dann lass es lieber. Ansonsten musst du halt mal etwas damit rumspielen, vielleicht kannst du noch was optimieren... Sind halt 5 Subselects. Wenn du die Indizes richtig gesetzt hast, wirst du kaum was merken.

@Cobinja:
Und genau das war es was mich so etwas ins Grübeln brachte.
 
Zuletzt bearbeitet:
Ja dann danke ich mal allen recht herzlich für die Resonanz hier im Forum und sage: Das Thema kann geschlossen werden, da das Problem gelöst ist.
 
Zurück
Oben