用另一条记录的结果替换空/空字符串

Posted

技术标签:

【中文标题】用另一条记录的结果替换空/空字符串【英文标题】:Replace empty/null string with result from another record 【发布时间】:2013-12-06 17:40:55 【问题描述】:

我有一个语言表,想要检索所选语言的特定记录。但是,当没有翻译时,我想获得另一种语言的翻译。

翻译

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"

程序数据

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

如果我想根据表 PROGDATA 中的 ID 翻译语言 3,那么我可以这样做:

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

这会给我:“Programista”“Kategoria”“Dzialanie”

如果是语言 1,我在第二条记录上得到一个空字符串:"Programmeur""""演员”

如何将空字符串替换为例如语言 2 的翻译?“Programmeur”“Category”“行动”

我尝试在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

【问题讨论】:

如果首选语言不可用,如何选择使用哪种语言? 始终填充默认语言,例如这可能是语言 2。无论如何,它是硬编码的。 如果未填充默认语言,则这是开发人员错误;)在这种情况下,我应该生成错误(但是,我将在 SQL 之外执行此操作)。 【参考方案1】:

SWITCHCASE 语句可能效果很好。但是试试这个:

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 

我使用TEXTOTHERTEXTFINAL 来减少字段名称的歧义。有时这会有所帮助。

您甚至可能需要将该原则应用于表名:

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

另外,请确保您的标准是正确的:空字符串,而不是 Null 值。

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

【讨论】:

我无法让它在 Access 中工作。 “子查询 'TEXT' 中的无效备注、OLE 或超链接对象”。这可能是因为子查询返回多个结果。所以我尝试比较第一个和第二个查询的 TAG:TRANSLATIONS_ALT.TAG = TRANSLATIONS_MAIN.TAG。然而,这并没有帮助。【参考方案2】:

您可以再次加入 TRANSLATIONS 表以获得“默认”翻译并在 SELECT 语句中使用 CASE。

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

【讨论】:

Access 为此目的使用Nz()IsNull() 仅返回 True 或 False。但是,由于 Access 的引擎首选项,建议构建 Iif() 语句而不是使用 Nz()。见allenbrowne.com/QueryPerfIssue.html#nz 显然,MS Access 中没有 CASE 语句。 ***.com/questions/772461/case-statement-in-access 你必须使用 IIf()【参考方案3】:

这是一个伪代码的想法... 我会尝试为返回的每个值添加一个 checkEmpty 函数。如果不为空,则返回相同的内容。如果为空,则从其他语言返回新的搜索。 当然,您需要再次检查新值是否为空。

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 TRANSLATIONS.LANG=@newlanguage  

    return @newWord
    end;

 end;

//函数调用

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

【讨论】:

从 Access 查询中调用 VBA 函数会导致效率问题,更重要的是在大多数情况下会导致代码可维护性问题。因此,不能通过诸如已接受的直接 SQL 解决方案来推荐此方法。然而,这是一个有创意且可行的想法。【参考方案4】:

我将@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

我从没想过以不同的别名引用一个表两次

【讨论】:

当您可以直接使用 NZ(或 ISNULL)时,为什么要使用 IF? ....选择新西兰(翻译.文本,默认.文本).... NZ(TRANSLATION.Text,"") = "" 是双重检查。它首先检查 NULL,然后检查空字符串。当 TRANSLATION 为 NULL 或 "" 时应使用 DEFAULT

以上是关于用另一条记录的结果替换空/空字符串的主要内容,如果未能解决你的问题,请参考以下文章

kettle怎么过滤掉某个字段空字符串数据

在查询SQL语句中为空或不为空怎么写

Rails 3.2:用json序列化中的空字符串替换空值

在查询SQL语句中为空或者不为空的字段应该怎么写?

空字符串或空变量的 JSON 标准是啥?

用空值替换空字符串