Select XOR

PosChris

Well-Known Member
#1
Moin,

ich verzweifele an dem Versuch, ein Backup-Szenario zu bauen über SQL. Ich händele es skripttechnisch momentan, aber es lässt mir keine Ruhe :)

Hintergrund:
Ich spiele meine Website mehrsprachig aus. Normalerweise ist jede Seite übersetzt in 2 verschiedene Sprachen (deutsch, französisch, englisch). In meinem französischen Bereich möchte ich immer alle Seiten ausspielen, die auch auf deutsch zur Verfügung stehen. Jedoch ist nicht gewährleistet, dass diese Seite schon übersetzt wurde. In dem Fall wird die erste verfügbare default-Seite geladen skripttechnisch. Das ganze würde ich gerne über Sql abbilden.

Standard-Fall für die französische Seite (Tabellen und Feld-Namen sind ausgedacht und ziemlich klein gehalten zum test)
SQL:
select * from meine_seiten
where SITE_ID="themenseite_test" and LANGUAGE_CODE="FR"
Ist die seite nicht verfügbar ist das result-set natürlich leer, und die nächst verfügbare Sprache wird mittels des nächsten Länder-Codes geladen.

Jetzt ist mein Gedanke, dass ich alle verfügbaren Sprachen abrufe und durch ein XOR die erst verfügbare bekomme, nur leider scheitere ich an der Ausgabe
SQL:
select * from meine_seiten
where SITE_ID="themenseite_test" and ( LANGUAGE_CODE="FR" XOR LANGUAGE_CODE="DE")
Die Bedingung ist wahr, also werden alle ausgespielt. Dumm gelaufen, das war nicht die Lösung :-(

Bekomm ich das irgendwie über ein having hin? Mit der XOR-Abfrage im Having bekomme ich auch beide ausgespielt
 

asc

Well-Known Member
c-b Experte
#2
Probiere es so:
Die bevorzugte Sprache bekommt ein höheres Ranking und mittels ORDER und LIMIT wird das beste Ergebnis ausgewählt

SQL:
select
  meine_seiten.*,
  IF(meine_seiten.LANGUAGE_CODE = "FR", 1, 0) language_matched
from meine_seiten
where
  SITE_ID="themenseite_test"
order by language_matched DESC
limit 1
 

PosChris

Well-Known Member
#3
ok danke, das funktioniert soweit.
angenommen, du willst mehrere seiten laden, dann funktioniert das system so leider auch nicht. da muss ich mir noch was überlegen
 

Jan Krüger

Well-Known Member
c-b Team
c-b Experte
#4
In SQL geht sowas meines Wissens nur mit einem Subquery oder Join. Eine Subquery-Variante:
SQL:
select * from meine_seiten ms1
where SITE_ID='themenseite_test' and (LANGUAGE_CODE='FR' or (
    LANGUAGE_CODE='DE' and not exists (
        select * from meine_seiten ms2 where LANGUAGE_CODE='FR' and ms2.SITE_ID = ms1.SITE_ID)
)));
Eine Join-Variante:
SQL:
select ms1.* from meine_seiten ms1 left join meine_seiten ms2
    on (ms1.SITE_ID = ms2.SITE_ID and ms2.SITE_ID='FR')
    where SITE_ID='themenseite_test' and (ms1.SITE_ID='FR' or (ms1.SITE_ID='DE' and ms2.SITE_ID is null));
PS. doppelte Anführungszeichen für Strings sind kein Standard-SQL, ich würde mir deshalb an deiner Stelle direkt angewöhnen, einfache Anführungszeichen zu benutzen.
 
Oben