Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien
Toon posts:

[mysql] Prioriteit OR operator

Pagina: 1
Acties:

Verwijderd

Topicstarter
Hallo,

De topic titel is niet helemaal zoals ik die bedoel, maar ik weet geen goede term hiervoor.

Ik heb een tabel met allemaal strings: language_strings AS ls, en een tabel met talen: languages AS l.

Nu heeft iedere taal een uid, en een fallback (uid). Zo is er een taalset voor kinderen en een voor volwassenen, waarbij die voor de volwassenen maar een kleine variatie op die van de kinderen is. De fallback daarvan is dus kinderen.

Nu wil ik met 1 query alle strings voor een bepaalde taal uit de database halen. Hiervoor doe ik nu:

[sql]WHERE l.name = _LANG_ AND ( ls.language_uid = l.uid OR ls.language_uid = l.fallback[/sql]

Ik selecteerd dus op de naam van de taal, en kijk dan of de uid ervan voorkomt, of de uid van de fallback (een taal kan maar 1 niveau diep "fallbacken".

Nu werkt dit, maar ik vraag mij af of dit toeval is, of dat dit altijd gegarandeerd het gewenste resultaat geeft. Dus dat ik altijd de taal zelf, OF fallback krijg, en niet de fallback als er voor die taal zelf ook een string is gedefineerd.

In de manual heb ik hier niets over terug kunnen vinden, mede omdat ik geen goede zoektermen weet.

Verwijderd

Nu werkt dit, maar ik vraag mij af of dit toeval is, of dat dit altijd gegarandeerd het gewenste resultaat geeft. Dus dat ik altijd de taal zelf, OF fallback krijg, en niet de fallback als er voor die taal zelf ook een string is gedefineerd.
Nee, je krijgt niet OF je krijgt EN.

stel de volgende tabel 'Tabel'

Naam
====
Jan
Jaap
Henk
Piet

SQL:
1
select Naam from Tabel where Naam="Jan" OR Naam="Piet"

Dan krijg je terug
Naam
====
Jan
Piet

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Verwijderd schreef op dinsdag 08 april 2008 @ 17:15:
mede omdat ik geen goede zoektermen weet.
operator precedence, en ja dat staat onder die term in de manual.

Maar bij twijfel moet je gewoon haakjes gebruiken. Dan geef je des te duidelijker aan wat de bedoeling is van die query en dat is ook weer aardig voor de volgende persoon die de code ziet.

{signature}


  • _js_
  • Registratie: Oktober 2002
  • Laatst online: 25-10 14:28
Als het goed is (ik weet niet zeker hoe je joins er uit zien) krijg je die strings die dubbel aanwezig zijn ook dubbel terug. OR betekent dat beide waarden geldig zijn. taal 1 met string 1 is dan geldig, maar ook taal 1 met fallback 1.

Wat je waarschijnlijk wilt is twee keer joinen en bij een niet bestaande waarde de fallback te gebruiken:
SELECT ISNULL(ls.string,fallback.string)
FROM l
LEFT JOIN ls ON l.id = ls.id
LEFT JOIN fallback ON l.fallback = fallback.id

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 23:43

.oisyn

Moderator Devschuur®

Demotivational Speaker

Voutloos schreef op dinsdag 08 april 2008 @ 17:32:
[...]
operator precedence, en ja dat staat onder die term in de manual.
Jammer alleen dat z'n probleem geen zak met operator precedence te maken heeft ;)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Anders lees ik het echte probleem niet goed... :X Maar goed, ik geef welk de mooie term voor prioriteit en daar werd ook (een klein beetje) om gevraagd. :+

En ik ga btw voor een aanpak met joins, zoals _js_ dus.

[ Voor 15% gewijzigd door Voutloos op 09-04-2008 08:18 ]

{signature}


  • Goodielover
  • Registratie: November 2001
  • Laatst online: 21-09 16:54

Goodielover

Only The Best is Good Enough.

Ik zou het oplossen met een IN (..... , ....) statement of met een UNION
dus eerst de talen selecteren die als preferred taal _LANG_ hebben en dan UNION talen die _LANG_ als fallback taal hebben.

De vraag is wil je verschillende records van de talen terug of meedere velden in één record.
En is elke taal maar één keer fallback (denk ik niet)? Maar bovenstaande oplossing zou moeten werken

  • BCC
  • Registratie: Juli 2000
  • Laatst online: 21:31

BCC

Ik zou dit in de businesslaag oplossen. in 99% van de gevallen is er waarschijnlijk een vertaling en volstaat een
select * from language_strings where name="monkey" en language="nl-NL" LIMIT 1;
Wanneer dit geen resultaten oplevert kun je een stapel fallback scenarios kickstarten (andere taal, partial match, string die je wil vertalen teruggeven, vertaler emailen dat er een vertaling mist, etc). Dit zal iets trager zijn dan helemaal in SQL, maar zal door je verhouding correcte hits / fallbacks waarschijnlijk sneller zijn.

Waarom zet je je vertalingen eigenlijk in de database? Heb je al naar zoiets als Gettext gekeken? Dat is bedoelt voor het vertalen van applicaties.

[ Voor 14% gewijzigd door BCC op 09-04-2008 08:28 ]

Na betaling van een licentievergoeding van €1.000 verkrijgen bedrijven het recht om deze post te gebruiken voor het trainen van artificiële intelligentiesystemen.


  • MarkvE
  • Registratie: Maart 2004
  • Laatst online: 30-01 17:16
Omdat er een vastgesteld aantal fallbacks zijn (1) kun je dit mooi oplossen met een CASE:

SQL:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
SELECT
    data,
    CASE
        WHEN
            ( SELECT COUNT(1) gewenste language ) = 1
        THEN
            ( SELECT gewenste language ) AS language
        ELSE
            ( SELECT fallback ) AS language
    END AS language
FROM
    table
WHERE
    id = int


Niet de meest elegante oplossing misschien, maar zo los je je probleem wel op met een query.

Vormkracht10


  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Het kan op 1001 manieren, maar functies als ISNULL() en COALESCE() zijn hier gewoon voor gemaakt en zijn imo mooier dan een CASE met maar 1 WHEN. ;)

{signature}


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 04:20
Ingewikkelde filters (WHERE clauses) en subqueries moet je zoveel mogelijk vermijden (hoewel sommige subqueries wel als een soort join uitgevoerd kunnen worden), maar cases selecteren in de projectiefase (de SELECT clause) is op zich wel efficient, mits je joins natuurlijk simpel genoeg zijn.

In dit geval is COALESCE je vriend: eerst een tabel maken waarin elk taalelement gecombineerd wordt met zowel de primair als de secundaire string, en daarna de juiste selecteren:

SQL:
1
2
3
4
5
SELECT COALESCE(a.waarde, b.waarde), ..
FROM talen
LEFT JOIN strings AS a ON a.id = talen.primair_id
LEFT JOIN strings AS b ON b.id = talen.secundair_id
WHERE talen.taal_id = 123

  • frickY
  • Registratie: Juli 2001
  • Laatst online: 18-11 14:08
Ik gebruik hier inderdaad ook altijd COALESCE voor. Deze functie geeft de eerste waarde terug die niet NULL is.

Maak een select op je fallback tabel en join hierop je incomplete tabel.
Voer je kolomnaam uit de incomplete tabel en de corresponderende kolom uit je fallback tabel in COALESCE; Ontbreekt de eerste kolom, dan krijg je de fallback kolom
Pagina: 1