Query MySQL di merda

Ciao 79, devo fare una query ma sono handicappato.

Per ora ho risolto così, e funziona, però non mi piace
http://pastebin.com/wa40vgUm


Risultato:
http://pastebin.com/3cU2PmrH *

Vediamo di fare un ER simil-decente.

Spoiler




Queste sono le corrispettive tabelle

Spoiler




Dump del database
http://pastebin.com/fqUfyNk9

L'entità essenze l'ho tradotta con la tabella essenze.
L'entità referencestourl l'ho tradotta con la tabella referencestourl.
L'entità lingua l'ho tradotta con l'entità essenzetransl.
La relazione traduzione l'ho collassata su essenzetransl.
Le altre due relazioni le ho collassate su essenze.

La query che mi serve è questa:
"seleziona tutte le essenze dal database con relativi url e relativa traduzione in inglese ('en'), preoccupandoti per ogni tupla di verificare se esiste o meno la traduzione in inglese. Se non esiste, restituisci la tupla in lingua italiana 'it'".

Ora, io ho risolto semplicemente UNENDO due select distinte: la prima che fa la selezione per la lingua inglese, la seconda che trova le sole tuple che non hanno una traduzione e in tal caso restituisce la traduzione italiana.
Non posso fare una left outer join e basta perché in tal caso, invece della traduzione italiana mi da una sfilza di null (giustamente).

Voi avete mica qualche idea?

* Nei dati c'è un errore. Ho sbagliato ad inserire una entry: il campo globe_url nella terza riga dovrebbe essere "globes/Europe.gif", comunque a livello di logica non cambia assolutamente nulla.
sarà che mi sono appena svegliato ma non riesco a seguirti molto...
puoi piemmarmi un backup delle tabelle con un po' di dati che ci do un'occhiata plz?

dal tuo schema non riesco a capire come sono fatte le tabelle
Ecco qua (pubblico, non c'è problema :P)
http://pastebin.com/fqUfyNk9

Come vedi, sulla tabella essenzetransl, alle chiavi (1,'en'), (2,'en') vengono riportate le tuple corrispondenti, mentre alla chiave (3,'en') non corrisponde alcuna tupla, quindi la query riporta la tupla (3,'it')
Adesso aggiorno anche il file con i risultati della query (ho aggiunto più dati per chiarezza)

Grazie mille per l'aiuto

EDIT: Aggiornati i risultati della query. Nei dati c'è un errore. Ho sbagliato ad inserire una entry: il campo globe_url nella terza riga dovrebbe essere "globes/Europe.gif", comunque a livello di logica non cambia assolutamente nulla.
ok ci sto guardando... intanto sappi che ti sto odiando fortissimo per la nomenclatura incomprensibile

edit: non si capisce un cazzo sulle FK !!! come sono cllegate le chiavi tra tabelle? thx

la confusione scorre potente in questo DB imho. questa query ti serve solo eng/ita o deve ritornare sempre e comunque l'italiano in caso la lingua scelta non ci fosse?
poi la gente mi chiede perchè non voglio usare mysql... stupido engine che non supporta le outer join e fa le join a cazzo


Solo eng/ita. Cioè, poi dopo quei parametri me li gestisco via PHP. Meglio non fare troppe cose con SQL

Allora, le FK... essenze.url_texture_ref ed essenze.url_globe_ref sono collegate a referencestourl.id mentre essenzetransl.id è collegata ad essenze.id

Comunque questo schema è la traduzione papale papale dell'er indicato sopra; unica differenza è che la tabella lingua l'ho chiamata essenzetransl.
BTW mysql supporta le outer join. Il problema è che non mi bastano. Ho un problema di espressività del linguaggio.

Non mi sembra particolarmente incasinato questo schema
Per ogni essenza, vi sono varie traduzioni in varie lingue (essenzetransl) e ad ogni essenza sono collegati due e solo due URL che possono essere usati anche da più essenze contemporaneamente.
guarda un po' se questa ti piace... è una mezza porcata, ma ottieni quello che vuoi.. se non ti piace ci sono altri modi direi

MySQL supporta le join, ma non ne fa un cartesiano come gli altri RDBMS, ergo ha un modo tutto suo che è una chiavica



SELECT
E.id,
E.def_title,
E.base_description,
RTU.url,
RTU2.url,
CASE WHEN ET.lang IS NULL THEN
(SELECT Lang
FROM essenzetransl as C1
WHERE C1.lang = 'IT'
AND E.id = C1.id)
ELSE ET.Lang END AS Lang,
CASE WHEN ET.title IS NULL THEN
(SELECT Title
FROM essenzetransl as C1
WHERE C1.lang = 'IT'
AND E.id = C1.id)
ELSE ET.Title END AS Title,
CASE WHEN ET.Description IS NULL THEN
(SELECT Description
FROM essenzetransl as C1
WHERE C1.lang = 'IT'
AND E.id = C1.id)
ELSE ET.Description END AS Description
FROM essenze AS E
LEFT JOIN ReferenceToUrl AS RTU
ON E.url_texture_ref = RTU.id
LEFT JOIN ReferenceToUrl AS RTU2
ON E.url_globe_ref = RTU2.id
LEFT JOIN essenzetransl AS ET
ON E.id = ET.id
AND ET.lang = 'en'
ORDER BY E.id


edit, cambiate due cazzate
Figata, non conoscevo l'esistenza del CASE. Grazie ancora.


in sql server veniva in 3 righe
btw, prego ci mancherebbe

il case è motto motto utile (ed è standard SQL)

PS: testala bene perchè potrebbe essere buggata eh
ah, un appunto allo stile se mi permetti: se decidi di usare un tipo sintassi per un operatore, usa sempre quello nella query.
nella tua query hai usato due modi diversi per fare la join:

#FROM essenze AS e, referencetourl AS r1, referencetourl AS r2
#WHERE e.url_texture_ref = r1.id AND e.url_globe_ref = r2.id

e

#LEFT OUTER JOIN essenzetransl et
# ON e1.id = et.id

così ti incasini il codice. nel caso specifico della JOIN ti consiglio di usare la sintsassi SQL99 (il secondo esempio) perchè è più corretto... l'altro è deprecato e verrà abbandonato presto mi pare.

cheers!


Hai ragione, è solo che non sono particolarmente ferrato in SQL, e non saprei fare a fare una join fra 3 tabelle senza appesantire l'espressione (cioè facendo una join di una join)

Tra l'altro ogni tanto uso
#foo AS bar
e ogni tanto
#foo bar



EDIT
Figata, ho scoperto che si può fare

SELECT *
FROM essenze AS e
JOIN referencetourl AS r1
JOIN referencetourl AS r2
ON e.url_texture_ref = r1.id
AND e.url_globe_ref = r2.id
LIMIT 0 , 30



Sono niubbo
Datemi un manuale di sql


best manual ever

vabbè torno a studiare per l'esame MCTS sql2008