我有一个消息表,其中包含消息ID字段,语言ID字段和文本字段。
应用程序需要根据id和语言显示消息,这些消息一起构成唯一键。语言EN
存在所有消息,但并非所有消息都已翻译成其他语言。因此,对于英语,将始终选择一个记录。但是如果用户是法语并且应用程序需要显示消息#17并且它还不存在法语,我想在EN
中返回消息#17。我想在一个SELECT
查询中完成此操作,最好不要使用IF
语句。
编辑:根据提交的答案 - 需要澄清每条消息被翻译成大约10种语言,甚至更多。根据消息ID和lang id,应始终完全 返回一行行。但如果该行不存在,则应返回英文消息。
最终代码:
declare @msgid int=2, @langid varchar(2)='fr'
SELECT isnull(xx.msg, en.msg) msgtext
FROM appmessages en
LEFT JOIN appmessages xx ON en.msgid = xx.msgid and xx.langid=@langid
WHERE en.langid = 'en' and en.msgid=@msgid
答案 0 :(得分:7)
您可以使用_g
和LEFT JOIN
来实现此目标
ISNULL
答案 1 :(得分:5)
一种简单的方法只是使用order by
来确定优先级:
select top 1 mt.*
from message_table mt
where mt.message_id = 17 and mt.language in ('French', 'English')
order by (case when mt.language = 'French' then 1 else 2 end);
对于单条消息,使用message_table(message_id, language)
上的索引优化性能。两行order by
是微不足道的,所以应该非常快。
即使某些消息没有英文翻译,这种方法也具有很好的特性。添加其他语言也非常简单,对处理时间的影响应该很小。
对于多个消息,您可以使用窗口函数执行类似的操作,但这将是一个不同的问题。
答案 2 :(得分:3)
DECLARE @UserLanguageID char(2)='fr',
@DefaultLanguageID char(2)='en'
SELECT
COALESCE(uMsg.KeyField, dMsg.KeyField) AS KeyField,
COALESCE(uMsg.LanguageID, dMsg.LanguageID) AS LanguageID,
COALESCE(uMsg.Text, dMsg.Text) AS Text
FROM
Messages dMsg
LEFT JOIN Messages uMsg
ON uMsg.KeyField=dMsg.KeyField
WHERE
(uMsg.KeyField=@KeyField OR dMsg.KeyField=@KeyField)
AND uMsg.LanguageID=@UserLanguageID
AND dMsg.KeyField=@DefaultLanguageID
答案 3 :(得分:0)
DECLARE @RequestedLanguageId NCHAR(2)
DECLARE @RequestedMessageId INT
SET @RequestedLanguageId = 'FR'
SET @RequestedMessageId = 18
SELECT
ISNULL(xx.message_text, en.message_text) AS MessageText
FROM message_table en
LEFT JOIN message_table xx
ON xx.message_id = en.message_id
AND xx.language_id = @RequestedLanguageId
WHERE (en.language_id = 'EN')
AND (en.message_id = @RequestedMessageId)
变量DECLAREs和SETs是为了让你测试它。
答案 4 :(得分:0)
declare @msgid int=2, @langid varchar(2)='fr'
SELECT isnull(xx.msg, en.msg) msgtext
FROM appmessages en
LEFT JOIN appmessages xx ON en.msgid = xx.msgid and xx.langid=@langid
WHERE en.langid = 'en' and en.msgid=@msgid