2013-12-06 6 views
1

У меня есть языковая таблица и вы хотите получить определенные записи для выбранного языка. Однако, когда нет перевода, я хочу получить перевод другого языка.Заменить пустую/пустую строку с результатом из другой записи

ПЕРЕВОДЫ

TAG  LANG TEXT 
"prog1" | 1 | "Programmeur" 
"prog1" | 2 | "Programmer" 
"prog1" | 3 | "Programista" 
"prog2" | 1 | "" 
"prog2" | 2 | "Category" 
"prog2" | 3 | "Kategoria" 
"prog3" | 1 | "Actie" 
"prog3" | 2 | "Action" 
"prog3" | 3 | "Dzialanie" 

PROGDATA

ID | COL1 | COL2 
1 | "data" | "data" 
2 | "data" | "data" 
3 | "data" | "data" 

Если я хочу переводы с языка 3 на основе идентификаторов в таблице PROGDATA, то я могу сделать:

SELECT TEXT FROM TRANSLATIONS, PROGDATA 
WHERE TRANSLATIONS.TAG="prog" & PROGDATA.ID 
    AND TRANSLATIONS.LANG=3 

который дал бы мне:
"Programista"
"Kategoria"
"Dzialanie"

В случае языка 1 я получаю пустую строку на второй записи:
«Programmeur "
""
"Actie"

Как заменить пустую строку, например, на перевод языка 2?
"Programmeur"
"Категория"
"Actie"

Я попытался гнездования новый запрос на выборку в качестве IIf() функции, но это явно не работает.

SELECT 
    IIf(TEXT="", 
    (SELECT TEXT FROM TRANSLATIONS, PROGDATA 
    WHERE TRANSLATIONS.TAG="prog" & PROGDATA.ID 
    AND TRANSLATIONS.LANG=2),TEXT) 
FROM TRANSLATIONS, PROGDATA 
WHERE TRANSLATIONS.TAG="prog" & PROGDATA.ID 
AND TRANSLATIONS.LANG=3 
+1

Если предпочтительный язык недоступен, как вы выбираете, какой язык для нас e вместо? – Smandoli

+0

Язык по умолчанию всегда заполняется, например. это может быть язык 2. Во всяком случае, он жестко закодирован. –

+0

Если язык по умолчанию не заполнен, это ошибка разработчика;) В этом случае я должен сгенерировать ошибку (но я сделаю это за пределами SQL). –

ответ

0

Я canabalized решения о @fossilcoder и @Smandoli и объединить его в одном решении:

SELECT 
    IIf (
    NZ(TRANSLATION.Text,"") = "", DEFAULT.TEXT, TRANSLATION.TEXT) 
FROM 
    TRANSLATIONS AS TRANSLATION, 
    TRANSLATIONS AS DEFAULT, 
    PROGDATA 
WHERE 
    TRANSLATION.Tag="prog_" & PROGDATA.Id 
    AND 
    DEFAULT.Tag="prog" & PROGDATA.Id 
    AND 
    TRANSLATION.LanguageId=1 
    AND 
    DEFAULT.LanguageId=2 

Я никогда не думал, ссылка на таблицу дважды под другим псевдонимом

+1

Почему ЕСЛИ, когда вы можете напрямую использовать NZ (или ISNULL)? .... SELECT NZ (TRANSLATION.Text, DEFAULT.TEXT) .... –

+0

NZ (TRANSLATION.Text, "") = "" является двойной проверкой. Сначала он проверяет значение NULL, а затем пустую строку. ПО УМОЛЧАНИЮ следует использовать, когда TRANSLATION является либо NULL, либо «" –

0

SWITCH или CASE заявление может хорошо работать. Но попробуйте это:

SELECT 
    IIf(TEXT="", 
    (SELECT TEXT AS TEXT_OTHER FROM TRANSLATIONS, PROGDATA 
    WHERE TRANSLATIONS.TAG="prog" & PROGDATA.ID 
    AND TRANSLATIONS.LANG=2),TEXT) AS TEXT_FINAL 

Я использую TEXTOTHER и TEXTFINAL, чтобы уменьшить неоднозначность в именах полей. Иногда это помогает.

Вы даже, возможно, потребуется применить этот принцип к имени таблицы:

(SELECT TEXT AS TEXT_OTHER FROM TRANSLATIONS AS TRANSLATIONS_ALT... 

Кроме того, убедитесь, что ваш критерий является правильным: пустая строка, а не нулевое значение.

IIf(TEXT="", ... 
IIf(ISNULL(TEXT), ... 
+0

Я не мог заставить это работать в Access. Msgstr "Недействительный Memo, OLE или объект гиперссылки в подзапросе 'TEXT'. Вероятно, это происходит потому, что подзапрос возвращает несколько результатов. Поэтому я попытался сравнить TAG с первым и вторым запросом: TRANSLATIONS_ALT.TAG = TRANSLATIONS_MAIN.TAG. Однако это не помогло. –

0

Вы можете снова присоединиться к таблице TRANSLATIONS, чтобы получить перевод «по умолчанию» и использовать CASE в инструкции SELECT.

SELECT 
CASE 
    WHEN ISNULL(Translation.TEXT,"") = "" THEN DefaultLang.TEXT 
    ELSE Translation.Text 
END 
FROM TRANSLATIONS AS DefaultLang,TRANSLATIONS as Translation, PROGDATA 
WHERE 
DefaultLang.TAG="prog" & PROGDATA.ID AND Translation.TAG="prog" & PROGDATA.ID 
AND DefaultLang.LANG=2 
AND Translation.LANG=3 
+0

Для этого для доступа используется 'Nz()'; 'IsNull()' возвращает только True или False. Тем не менее, рекомендуется создать инструкцию 'Iif()' вместо использования 'Nz()', из-за предпочтений двигателя Access. См. Http://allenbrowne.com/QueryPerfIssue.html#nz – Smandoli

+0

По-видимому, в MS Access нет инструкции CASE. http://stackoverflow.com/questions/772461/case-statement-in-access –

+0

Вместо этого вы должны использовать IIf() –

0

это идея псевдо-код ... Я d пытаюсь добавить функцию checkEmpty для каждого значения, возвращаемого. если не пусто, верните то же самое ..if is empty возвращает новый поиск от другого языка. Вам нужно обмануть, что новое значение, конечно, не пустое.

create function checkEmpty(@word varchar(10), @languageNumber integer) returns varchar(10) 
    as 
    begin 
    declare @newWord 
    declare @newlanguage 

    if @word <> '' then return @word else 
     begin 
     //select new language 
     case languageNumber of 
     3 then @newlanguage = 1; 
     2 then @newlanguage = 3; 
     1 then @newlanguage = 2; 

     //search new lenguage 
     @newWord= SELECT TEXT FROM TRANSLATIONS, PROGDATA 
     WHERE TRANSLATIONS.TAG="prog" & PROGDATA.ID 
      AND [email protected] 

    return @newWord 
    end; 

end; 

// ФУНКЦИЯ ВЫЗОВ

SELECT dbo.checkEmpty(TEXT) FROM TRANSLATIONS, PROGDATA 
WHERE TRANSLATIONS.TAG="prog" & PROGDATA.ID 
    AND TRANSLATIONS.LANG=3 
+0

Вызов функции VBA из запроса Access создает проблемы для повышения эффективности и, что более важно, в большинстве случаев ремонтопригодность кода. Таким образом, это не может быть рекомендовано в отношении прямого SQL-решения, такого как принятое. Это, однако, творческая и работоспособная идея. – Smandoli

Смежные вопросы