Forum: PC-Programmierung SQLite Abfrage über mehrere Tabellen


von linguist (Gast)


Lesenswert?

Hallo allerseits,

es ist schon eine Weile her, dass ich mal was mit MySQL gemacht habe. 
Ich möchte eine kleine Wörterbuchanwendung schreiben, und habe folgendes 
Schema angedacht:

               Beispieldaten
words
 id        0       1       2
 word      "hallo" "hello" "hola"
 lang      "de"    "en"    "es"

links
 id        0 1
 word_id1  0 0
 word_id2  1 2


Kommt man bei diesem Schema mit einer Abfrage aus, um alle Übersetzungen 
eines Wortes zu ermitteln?
Noch schwieriger ist dann ja die Abfrage nach "hello" -> "hallo", "hola"


Ein erster Anfang
1
SELECT * 
2
FROM words
3
JOIN links
4
     ON (words.id = links.word_id1 OR words.id = links.word_id2 )
5
WHERE word = "hallo"

Aufgrund des JOIN müssen auf jeden Fall noch die Suchergebnisse 
eingeschränkt werden..

von R. M. (rmax)


Lesenswert?

Was genau möchtest Du in der Datenbank abbilden/speichern und welches 
Ergebnis soll die Query liefern?

von linguist (Gast)


Lesenswert?

Hallo,
ich möchte alle Übersetzungen eines Wortes ermitteln (wahlweise noch 
andere Parameter, z.B. die Zielsprache)

von R. M. (rmax)


Lesenswert?

Du mußt die Tabelle words in der Query zweimal verwenden, einmal für die 
Quellsprache und einmal für die Zielsprache(n):
1
SELECT *
2
FROM words wfrom
3
JOIN links
4
     ON ( wfrom.id = links.word_id1 OR wfrom.id = links.word_id2 )
5
JOIN words wto
6
     ON ( links.word_id1 = wto.id OR links.word_id2 = wto.id )
7
WHERE wfrom.word = "hallo"
8
  AND wfrom.lang != wto.lang

Damit bekommst Du in Deiner Beispieldatenbank zwei Ergebniszeilen, eine 
für hallo -> hello und eine für hallo -> hola. Die letzte Zeile des 
Statements schließt aus, daß Du auch noch eine für hallo -> hallo 
bekommst.

> Aufgrund des JOIN müssen auf jeden Fall noch die Suchergebnisse
> eingeschränkt werden..

Das machen ja bereits die ON-Klauseln.

von Self (Gast)


Lesenswert?

Dein Schema ist ein bisschen gar kompliziert. Mach doch einfach eine 
Tabelle mit den Spalten:
- id
- en
- de
- es

Oder, wenn es denn sein muss:
- id
- key (z.B. das Wort auf Englisch)
- lang (z.B. "de")
- word (z.B: "Hallo")

von R. M. (rmax)


Lesenswert?

Self schrieb:
> Mach doch einfach eine Tabelle mit den Spalten:
> - id
> - en
> - de
> - es

Das sieht auf den ersten Blick einfacher aus, aber um eine weitere 
Sprache hinzuzufügen, muß man gleich das Schema (und damit i.d.R. auch 
den SQL-Code der darauf zugreift) ändern.

von linguist (Gast)


Lesenswert?

Danke für die Hilfe!

von Vlad T. (vlad_tepesch)


Lesenswert?

linguist schrieb:
> Beispieldaten
> words
>  id        0       1       2
>  word      "hallo" "hello" "hola"
>  lang      "de"    "en"    "es"
>
> links
>  id        0 1
>  word_id1  0 0
>  word_id2  1 2

üblicherweise stellt man Datensätze untereinander da

Ich würde für die Sprache auch eine eigene Tabelle bauen und in words 
nur die langs.id referenzieren.
langs
id  lang
0   "de"
1   "en"

alle Übersetzungen eines Wortes zu ermitteln ist mit einer Abfrage 
nicht möglich.
da ja eine Verbindung en-es auch über en-de und de-es möglich sein 
könnte.
Du kannst natürlich eine Mastersprache definieren, so dass word_id1 
immer auf die Übersetzung in der Mastersprache referenziert.
Dann kannst du in die du in der ersten Stufe der Abfrage die 
Übersetzungen in die Mastersprache holen und in der zweiten Stufe der 
Abfrage alle Übersetzungen.
Die Frage ist natürlich wie präzise diese Übersetzungen denn wären.
Such mal auf Leo nach einem Wort und übersetze dann alle Ergebnisse 
zurück in die Ausgangssprache. Der so entstandenen Baum wird nicht sehr 
zufriedenstellend sein.

Einfach nur ohne diese Kettenübersetzungen ist die Abfrage einfach, wie 
R. Max es gezeigt hat.

von (prx) A. K. (prx)


Lesenswert?

Einfacheres Schema:

words
 id        0       0       0      1       1
 word      "hallo" "hello" "hola" "merde" "shit"
 lang      "de"    "en"    "es"   "fr"    "en"

select word, lang
  from words
 where id = (select id from words where word = "hallo" and lang = "de")
   and lang <> "de"

von linguist (Gast)


Lesenswert?

Vlad Tepesch schrieb:
> alle Übersetzungen eines Wortes zu ermitteln ist mit einer Abfrage
> nicht möglich.
> da ja eine Verbindung en-es auch über en-de und de-es möglich sein
> könnte.

Deswegen bin ich nochmal hier. Das geht mit obigem JOIN nämlich nicht. 
Ich hatte zwischendurch auch eine Abfrage mit subqueries. Und die 
Sprachen sind auch schon in einer eigenen Tabelle..
Evtl. kann man die "links" wichten.

Na, jedenfalls komm' ich langsam wieder ins Thema.
Danke auch für eure Beiträge!

von Vlad T. (vlad_tepesch)


Lesenswert?

A. K. schrieb:
> Einfacheres Schema:

das geht nicht.

ÜBerleg mal zB das deutsche Wort Schiefer, das für zwei unterschiedliche 
Sachen steht (Holzsplitter oder Gestein)
...
Ich denke das Problem wird klar.

von R. M. (rmax)


Lesenswert?

Das Schema schließt doch nicht aus, daß ein Wort unter verschiedenen IDs 
mehrfach vorkommt, wenn es unterschiedliche Bedeutungen hat.

von (prx) A. K. (prx)


Lesenswert?

Wobei es korrekterweise
   where id in (select id ...
heissen muss.

von R. M. (rmax)


Lesenswert?

Ja, oder halt gleich ein Join.

von Unterbezahlt (Gast)


Lesenswert?

R. Max schrieb:
> Self schrieb:
>> Mach doch einfach eine Tabelle mit den Spalten:
>> - id
>> - en
>> - de
>> - es
>
> Das sieht auf den ersten Blick einfacher aus, aber um eine weitere
> Sprache hinzuzufügen, muß man gleich das Schema (und damit i.d.R. auch
> den SQL-Code der darauf zugreift) ändern.

Kommt darauf an was man will. Akademisch richtig ist es nicht. Dafür 
einfach, schnell (auch für die Datenbank) und übersichtlich. Und den 
SQL-Code kann man auch hier generisch schreiben. Von einem praktischen 
Standpunkt aus also durchaus zu überlegen.

von Vlad T. (vlad_tepesch)


Lesenswert?

Unterbezahlt schrieb:
> Dafür
> einfach, schnell (auch für die Datenbank)
 und wie sieht es aus, wenn es mehrere Übersetzungen für ein Wort gibt?
wieviele de, en und es Spalten willst du denn dann noch an die Tabelle 
hängen?

Sowas ist einfach Murks.

von SQLo (Gast)


Lesenswert?

Vlad Tepesch schrieb:
> Unterbezahlt schrieb:
>> Dafür
>> einfach, schnell (auch für die Datenbank)
>  und wie sieht es aus, wenn es mehrere Übersetzungen für ein Wort gibt?
> wieviele de, en und es Spalten willst du denn dann noch an die Tabelle
> hängen?
>
> Sowas ist einfach Murks.

Das kannst du so nicht sagen. Es kommt darauf an, was man erreichen 
will. Wenn es eine Übersetzungstabelle für ein Programm werden soll, 
dann legt man eben für jede Wortbedeutung einen Eintrag in allen 
Sprachen ab.
Das ist wir gesagt super einfach, flott, wartbar und durchschaubar. Man 
muss nicht alles überkompliziert machen. Da sind mehrfache Joins für so 
eine einfache Aufgabe vollkommen unnötig und überdimensioniert. Und ist 
daher meiner Meinung nach der eigentliche Murks. Einen guten Entwickler 
zeichnen gerade solch einfache Lösungen aus, wenn sie ausreichend sind.

von Vlad T. (vlad_tepesch)


Lesenswert?

SQLo schrieb:
> Das kannst du so nicht sagen. Es kommt darauf an, was man erreichen
> will. Wenn es eine Übersetzungstabelle für ein Programm werden soll,
> dann legt man eben für jede Wortbedeutung einen Eintrag in allen
> Sprachen ab.

auch für sowas ist es Murks.
Was ist, wenn jemand die Unterstützung für eine weitere Sprache 
hinzufügen will?
Da muss das Tabellenlayout geändert werden - super!

SQLo schrieb:
> Das ist wir gesagt super einfach, flott, wartbar und durchschaubar.
wartbar ist das definitiv nicht, wenn durch hinzufügen einer Sprache die 
Tabelle angepasst werden muss. Wartbar ist, wenn nur ein paar Einträge 
dazu kommen.

flott?
Ich würde wetten, dass nahezu kein Unterschied messbar ist.

SQLo schrieb:
> Einen guten Entwickler zeichnen gerade solch einfache Lösungen aus,
Bitte nicht "einfache Lösungen" mit Murks gleichsetzen.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.