Ermittlung einer bedingten Übersetzung in SQL
Frage eines Usenet-Autors
Wenn Übersetzung gegeben, dann nimm diese, sonst Original.
Antwort von Stefan Ram
Ich nehme im folgenden Englisch als Fehlsprache.
Hier mal eine Idee:
DROP DATABASE IF EXISTS D201409190010180200;
CREATE DATABASE D201409190010180200; USE D201409190010180200;
CREATE TABLE MESSAGE ( TEXT VARCHAR (255), PRIMARY KEY( TEXT ));
INSERT INTO MESSAGE ( TEXT ) VALUES ( 'TIME' );
INSERT INTO MESSAGE ( TEXT ) VALUES ( 'PERSON' );
INSERT INTO MESSAGE ( TEXT ) VALUES ( 'YEAR' );
CREATE TABLE TRANSLATION
( TEXT VARCHAR (255), LANGUAGE VARCHAR (255),
TRANSLATION VARCHAR (255), PRIMARY KEY( TEXT ));
INSERT INTO TRANSLATION
( TEXT, LANGUAGE, TRANSLATION ) VALUES ( 'TIME', 'DEUTSCH', 'ZEIT' );
SELECT * FROM MESSAGE;
+--------+
| TEXT |
+--------+
| PERSON |
| TIME |
| YEAR |
+--------+SELECT * FROM TRANSLATION;
+------+----------+-------------+
| TEXT | LANGUAGE | TRANSLATION |
+------+----------+-------------+
| TIME | DEUTSCH | ZEIT |
+------+----------+-------------+SELECT IFNULL( TRANSLATION, MESSAGE.TEXT ) FROM MESSAGE LEFT JOIN
( SELECT TEXT, TRANSLATION FROM TRANSLATION WHERE LANGUAGE = 'DEUTSCH' )
AS TRANSLATED ON MESSAGE.TEXT = TRANSLATED.TEXT;
+-------------------------------------+
| IFNULL( TRANSLATION, MESSAGE.TEXT ) |
+-------------------------------------+
| PERSON |
| ZEIT |
| YEAR |
+-------------------------------------+
Lösung ohne IFNULL
Da gelegentlich empfohlen wird, denn Wert NULL zu vermeiden, wäre es interessant, wie man dann überhaupt eine Aufgabe wie die vorstehende lösen kann. Hier eine Möglichkeit:
DROP DATABASE IF EXISTS D201409190010180200;
CREATE DATABASE D201409190010180200; USE D201409190010180200;
CREATE TABLE MESSAGE ( TEXT VARCHAR (255), PRIMARY KEY( TEXT ));
INSERT INTO MESSAGE ( TEXT ) VALUES ( 'TIME' );
INSERT INTO MESSAGE ( TEXT ) VALUES ( 'PERSON' );
INSERT INTO MESSAGE ( TEXT ) VALUES ( 'YEAR' );
CREATE TABLE TRANSLATION
( TEXT VARCHAR (255), LANGUAGE VARCHAR (255),
TRANSLATION VARCHAR (255), PRIMARY KEY( TEXT ));
INSERT INTO TRANSLATION
( TEXT, LANGUAGE, TRANSLATION ) VALUES ( 'TIME', 'DEUTSCH', 'ZEIT' );
SELECT TEXT, TRANSLATION FROM
( SELECT * FROM
( SELECT MESSAGE.TEXT,
LANGUAGE,
TRANSLATION FROM MESSAGE
JOIN TRANSLATION ON MESSAGE.TEXT = TRANSLATION.TEXT )
AS HASTRANSLATION
UNION
SELECT * FROM
( SELECT DISTINCT DIRECTIONS.TEXT, LANGUAGE, DIRECTIONS.TEXT AS TRANSLATION
FROM
( SELECT MESSAGE.TEXT, LANGUAGE FROM MESSAGE,
( SELECT DISTINCT LANGUAGE FROM TRANSLATION )
AS LANGUAGE )
AS DIRECTIONS
WHERE (DIRECTIONS.TEXT,LANGUAGE) NOT IN
( SELECT HASATRANSLATION.TEXT, LANGUAGE FROM
( SELECT * FROM
( SELECT MESSAGE.TEXT,
LANGUAGE,
TRANSLATION FROM MESSAGE
JOIN TRANSLATION ON MESSAGE.TEXT = TRANSLATION.TEXT ) AS TRANSLATIONS )
AS HASATRANSLATION ))
AS HASNOTRANSLATION ) AS RESULT WHERE LANGUAGE = 'DEUTSCH';
Die voranstehende Lösung ist wegen der vielen verschachtelten Abfragen unübersichtlich und enthält Wiederholungen. Übungsaufgabe: Verwenden Sie Views, um beide Mängel zu beheben!