Thread SQL - Sprachauswahl WHERE-Klausel mit "Fallback"?: Geht sowas? (5 answers)
Opened by renee at 2006-01-31 00:08

murphy
 2006-01-31 03:22
#10358 #10358
User since
2004-07-19
1776 Artikel
HausmeisterIn
[Homepage]
user image
Naja, also mit relationalen Joins alleine kommt man da, glaube ich, noch nicht zum gewünschten Ergebnis. Das einzige was mit als Lösungsansatz einfällt sind verschachtelte SELECTs. Ich gebe mal ein Beispiel, das ich mit SQLite ausprobiert habe. Testdaten:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#!/bin/sh
sqlite3 blubb.db <<EOD
CREATE TABLE items(id INTEGER, level INTEGER, PRIMARY KEY(id));
INSERT INTO items VALUES(1, 1);
INSERT INTO items VALUES(2, 1);
INSERT INTO items VALUES(3, 2);
INSERT INTO items VALUES(4, 3);
INSERT INTO items VALUES(5, 3);
INSERT INTO items VALUES(6, 3);

CREATE TABLE translations(id INTEGER, lang TEXT, name TEXT, UNIQUE(id, lang));
INSERT INTO translations VALUES(1, 'en', 'buy');
INSERT INTO translations VALUES(1, 'de', 'kaufen');
INSERT INTO translations VALUES(1, 'is', 'kaupa');
INSERT INTO translations VALUES(1, 'fr', 'acheter');
INSERT INTO translations VALUES(2, 'en', 'sell');
INSERT INTO translations VALUES(2, 'is', 'selja');
INSERT INTO translations VALUES(3, 'is', 'laera');
INSERT INTO translations VALUES(3, 'fr', 'apprendre');
INSERT INTO translations VALUES(4, 'de', 'trinken');
INSERT INTO translations VALUES(4, 'en', 'drink');
INSERT INTO translations VALUES(4, 'is', 'drekka');
INSERT INTO translations VALUES(5, 'en', 'quit');
INSERT INTO translations VALUES(6, 'fr', 'annuler');
EOD


Und jetzt die Abfrage:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#!/usr/bin/perl -T
use strict;
use warnings;

use DBI;

my $db = DBI->connect('dbi:SQLite:dbname=blubb.db',
'', '',
{ RaiseError => 1 });


my $stmt = $db->prepare(<<'EOD');
SELECT
(CASE
WHEN t.lang ISNULL THEN
(SELECT name FROM translations WHERE id = i.id)
ELSE
t.name
END) AS name
FROM
items AS i LEFT OUTER JOIN translations AS t
ON
i.id = t.id AND t.lang = ?
WHERE i.id = ? AND i.level = ?;
EOD

sub x {
printf "lang = %s, id = %d, level = %d ==> ", @_;
$stmt->execute(@_);
print $stmt->fetchrow_array();
print "\n";
}

x('is', 2, 1);
x('de', 2, 1);

$stmt->finish();
$db->disconnect();


Funktioniert, ist aber nicht gerade schön und vermutlich auch nicht wahnsinnig schnell, wenn man viele Datensätze hat.
When C++ is your hammer, every problem looks like your thumb.

View full thread SQL - Sprachauswahl WHERE-Klausel mit "Fallback"?: Geht sowas?