2011-02-21 19 views
5

Me enfrento a la siguiente situación.Clasificación compleja en la base de datos MySQL

Tenemos un CMS con una entidad con traducciones. Estas traducciones se almacenan en una tabla diferente con una relación de uno a muchos. Por ejemplo, newsarticles y newsarticle_translations. La cantidad de languages disponible se determina dinámicamente por el mismo CMS.

Al ingresar un nuevo artículo, el editor debe ingresar al menos una traducción, que uno de los idiomas disponibles que elija depende de él.

En la descripción del nuevo artículo en nuestro CMS nos gustaría mostrar una columna con el título del artículo (traducido), pero como ninguno de los idiomas es obligatorio (uno de ellos es obligatorio pero no sé cuál) realmente no sé cómo construir mi consulta mysql para seleccionar un título para cada nuevo artículo, independientemente del idioma ingresado.

Y para hacerlo todo un poco más difícil, nuestro gerente pidió la posibilidad de también poder ordenar el título, por lo que descartar las traducciones en una consulta separada se descarta por lo que yo sé.

¿Alguien tiene una idea sobre cómo resolver esto de la manera más eficiente?

Éstos son que mi mesa de esquema que podría ayudar

> desc news; 
+-----------------+----------------+------+-----+-------------------+----------------+ 
| Field   | Type   | Null | Key | Default   | Extra   | 
+-----------------+----------------+------+-----+-------------------+----------------+ 
| id    | int(10)  | NO | PRI | NULL    | auto_increment | 
| category_id  | int(1)   | YES |  | NULL    |    | 
| created   | timestamp  | NO |  | CURRENT_TIMESTAMP |    | 
| user_id   | int(10)  | YES |  | NULL    |    | 
+-----------------+----------------+------+-----+-------------------+----------------+ 


> desc news_translations; 
+-----------------+------------------+------+-----+---------+----------------+ 
| Field   | Type    | Null | Key | Default | Extra   | 
+-----------------+------------------+------+-----+---------+----------------+ 
| id    | int(10) unsigned | NO | PRI | NULL | auto_increment | 
| enabled   | tinyint(1)  | NO |  | 0  |    | 
| news_id   | int(1) unsigned | NO |  | NULL |    | 
| title   | varchar(255)  | NO |  |   |    | 
| summary   | text    | YES |  | NULL |    | 
| body   | text    | NO |  | NULL |    | 
| language  | varchar(2)  | NO |  | NULL |    | 
+-----------------+------------------+------+-----+---------+----------------+ 

PS: He aunque sobre subconsultas y se unen() soluciones, pero los trucos parecen más bien sucios, preguntándose si algo mejor es saber que estoy no pensando en?

+1

tendría sentido tener también un 'title' campo en la tabla' news' que sería utilizado como el título predeterminado para un artículo de noticias? Incluso si es solo para uso de back-end? –

+0

Sería pero ese tipo de redundancia sería mi último recurso. Estoy buscando una solución más limpia/mejor, pero gracias por la sugerencia. – ChrisR

+0

Quizás un IZQUIERDA ÚNETE? – Benubird

Respuesta

1

Este no es un enfoque rápido, pero creo que le da lo que quiere.
quiero saber cómo funciona, y podemos trabajar en la velocidad próxima :)

select nt.title 
    from news n 
    join news_translations nt on(n.id = nt.news_id) 
where nt.title is not null 
    and nt.language = (
      select max(x.language) 
      from news_translations x 
      where x.title is not null 
      and x.new_id = nt.news_id) 
order 
    by nt.title; 
+0

gracias, no es lo que necesitaba, ¡pero me puso en camino para encontrar la solución perfecta! – ChrisR

1

Suponiendo que he leído correctamente su problema, ¿desea obtener una lista de títulos para artículos, prefiriendo el idioma "requerido"? Una consulta para que pudiera ir en la línea de ...

SELECT * FROM (
    SELECT nt.`title`, nt.news_id 
    FROM news n 
     INNER JOIN news_translations nt ON (n.id = nt.news_id) 
    WHERE title != '' 
    ORDER BY 
     CASE 
      WHEN nt.language = 'en' THEN 3 
      WHEN nt.language = 'jp' THEN 2 
      WHEN nt.language = 'de' THEN 1 
      ELSE 0 END DESC 
) AS t1 
GROUP BY `news_id` 

En este ejemplo se prefiere un título en Inglés (en) si está disponible, Japanese (JP) como segunda preferencia, y el alemán (DE) como una tercera , pero mostrará la primera entrada "otra" si ninguno de los idiomas solicitados está disponible.

+0

Casi, el orden no es el problema, es seleccionar el registro correcto de la tabla news_translations que tiene un título ingresado. He intentado su consulta y aún hay situaciones en las que se devuelve un título vacío, aunque uno de los títulos se ingrese en los registros de traducción relacionados. – ChrisR

+2

Oh, ya veo ... No me di cuenta de que habría entradas en blanco allí. Podría resolverlo agregando un "DONDE título! = ''/IS NOT NULL" a la selección interna. Déjame saber cómo te va, o si me he perdido el punto de nuevo :) –

Cuestiones relacionadas