LINUX.ORG.RU

Мультиязычность: помогите с SQL


0

1

Приветствую!

Есть табличка с полями: id, smth, lang Нужно вывести N записей `smth` на русском языке (lang=ru), при отсутствии русского - недостающие вывести на английском (lang=en).

Например, в БД есть следующие значения:

  • id, smth, lang
    • 1, Vasya, en
    • 1, Вася, ru

    • 2, John, en
    • 2, Джон, ru

    • 3, Sam, en

    • 4, Tom, en
    • 4, Том, ru

Результат должен быть следующим:

  • Вася
  • Джон
  • Sam
  • Том

Как модифицировать

SELECT `smth` FROM `somewhere` WHERE `lang`='ru' LIMIT N
дабы получить такое чудо? Или как изменить архитектуру, чтобы в конечном счете это реализовать? Благодарю.


Сделай два запроса.

zz ★★★★
()

Приведи данные к нормальной форме: одна сущность = одна запись.

CREATE TABLE ( 
   id       int PRIMARY KEY, 
   name_rus varchar, 
   name_eng varcar,
   CHECK( name_rus IS NOT NULL OR name_eng IS NOT NULL )
);
soomrack ★★★★★
()

Есть табличка с полями: id, smth, lang Нужно вывести N записей `smth` на русском языке (lang=ru), при отсутствии русского - недостающие вывести на английском (lang=en).

SELECT 
    if(
        `b`.`id` IS NULL, 
        `a`.`smth`, 
        `b`.`smth`
    ) as `smth`
FROM 
`somewhere` as `a` 
    LEFT JOIN 
`somewhere` as `b` 
    ON `a`.`id`=`b`.`id`
WHERE 
    `a`.`lang`='en' 
LIMIT N
r_asian ★☆☆
()
Ответ на: комментарий от soomrack

Баллииин... Вот же как надо!

Спасибо!

//Мне для другой похожей надобности.

Hoodoo ★★★★★
()
Ответ на: комментарий от r_asian

Похоже это то, что надо. Правда в ORM CakePHP такое без поллитра не засунуть.

Всех благодарю за ответы. Буду медитировать над предложенными решениями.

Test11
() автор топика
Ответ на: комментарий от soomrack

Тоже так думал, но полей много (name_en - name_ru, info_en - info_ru...), да и количество языков не фиксированное.

Test11
() автор топика
Ответ на: комментарий от soomrack

вы понимаете под нормальной формой что-то странное..

qnikst ★★★★★
()
select smth from
(select smth from somewhere where lang='ru'
union all
select smth from somewhere where lang='en')
limit N
anonymous
()
Ответ на: комментарий от soomrack

Приведи данные к нормальной форме: одна сущность = одна запись.

это как раз денормализованная форма

mashina ★★★★★
()
Ответ на: комментарий от Test11

в конкретном данном случае не сильно облегчит, зато позволит не переводить часть полей. Ну или в крайнем случае entity и entity_i18n

SELECT * FROM entity LEFT JOIN (SELECT i1.id_entity, IF(i1.id IS NULL,i1.name,i2.name) FROM entity_i18n i LEFT JOIN entity_i18n i on i.id_entity = i2.id_entry WHERE i1.lang = 'ru' and i2.lang='en') as t on t.id_entity = e.id LIMIT 5
qnikst ★★★★★
()
Ответ на: комментарий от mashina

это как раз денормализованная форма

Вообще-то нормальная. Ибо два разных человека (сущности) могут иметь одинаковый набор атрибутов (имена).

Вторая нормальная форма = перва нормальная форма + «все атрибуты кроме ключа зависят только от этого ключа, если логический ключ отсутствует, его надо создать».

Поэтому можно эти атрибуты оставлять в одной таблице.

Можно, конечно, завести таблицу для каждого языка. И так будет удобней, когда атрибутов будет много.


CREATE TABLE names (
   name varchar(32) NOT NULL
);

CREATE TABLE names_eng (
   id   int   PRIMARY KEY REFERENCES users_id ON DELETE CASCADE ON UPDATE CASCADE,
   LIKE names
);


CREATE TABLE names_rus (
   id   int   PRIMARY KEY REFERENCES users_id ON DELETE CASCADE ON UPDATE CASCADE,
   LIKE names
);

soomrack ★★★★★
()
Ответ на: комментарий от soomrack

PS. имя на русском не однозначно переводится на английский. Многие выбирают так как им удобней. Правила транслитерации меняются. Поэтому name_eng не определяется name_rus, это два разных, не зависимых друг от друга атрибута.

soomrack ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.