我正在开发一个多语言网站 PHP,如果可用,希望获取给定语言的内容,如果没有,则获取另一种语言的内容。我将尝试在下面解释我的问题。如果有什么不清楚的,请告诉我。
我的表:
content
: content_id
, url
, date
content_l10n
: content_id
, l10n_id
, title
, description
l10n
: l10n_id
, name
, order
第一种情况:
→ 使用
JOIN
易于实现。第二种情况:
→ 如何实现?是否可以在单个请求中?
一些注意事项:
content
行(例如,对于标题列表)。 title
被翻译,但 description
是 NULL
。理想情况下,请求会选择给定语言的标题,但会回退到另一种语言的描述。 l10n
中的语言,由 order
ASC 排序)。 您的帮助将不胜感激!先感谢您 !
亲切的问候,
奥利维尔
最佳答案
此解决方案适用于多行,但每种语言需要 1 个 LEFT JOIN,并且 JOIn 的顺序指定优先级。
SELECT c.url, c.date,
COALESCE( c1.title, c2.title ),
COALESCE( c1.description, c2.description )
FROM content c
LEFT JOIN content_l10n c1 ON (c1.content_id = c.content_id AND c1.l10n_id=$1)
LEFT JOIN content_l10n c2 ON (c2.content_id = c.content_id AND c2.l10n_id=$2)
(注意:我在这里假设 $1 和 $2 是用户的前 2 种首选语言,并且它们缓存在 session 中,因此不需要使用 l10n 进行额外的 JOIN)。
对于您的表结构,这是设置语言顺序的唯一有意义的方法。您需要一个额外的表来指定每个用户的语言首选项,而不是将顺序存储在 l10n 表中。所以让我们假设你有一张 table
user_l10n( user_id, l10n_id, order )
假设表 l10n 保留其“订单”字段作为默认值。
如果你这样做:
SELECT ..., COALESCE(ul.order,l.order) AS order
FROM
content c
JOIN content_l10n cl USING (content_id)
JOIN l10n l USING (l10n_id) -- get default language order
LEFT JOIN user_l10n ul ON (ul.l10n_id=l.l10n_id -- get user preferences if available
AND ul.user_id=$user_id)
WHERE search condition on content, etc
ORDER BY content_id, COALESCE(ul.order,l.order)
您将获得所有匹配的文档,以及用户指定(或默认)的排序,因此应用程序可以轻松地对此进行排序。
现在的想法是避免从数据库中检索所有使用用户喜欢的语言的现有翻译“遮蔽”的语言的行。
这样做的自然方法是 GROUP BY,但 MySQL 没有可以在这里工作的聚合函数......
你可以做一个依赖子查询(标题和描述);这可以抓取一行,但如果您想抓取多行,速度会非常慢。
但你也可以做其他事情!这依赖于 MySQL 的非标准 GROUP BY 子句的一些阴暗行为......
首先,收集要显示的“content_id”列表(分页搜索查询的结果,无论如何)。然后你可以做类似下面的恐怖的事情:
SELECT * FROM
(
SELECT content_id, title FROM
(
SELECT c.content_id, c.title
FROM
content c
JOIN content_l10n cl USING (content_id)
JOIN l10n l USING (l10n_id)
LEFT JOIN user_l10n ul ON (ul.l10n_id=l.l10n_id AND ul.user_id=$user_id)
WHERE cl.content_id IN ($list) AND c.title IS NOT NULL
ORDER BY content_id, COALESCE(ul.order,l.order)
) d GROUP BY content_id
) t
JOIN
(
SELECT content_id, description FROM
(
SELECT c.content_id, c.description
FROM
content c
JOIN content_l10n cl USING (content_id)
JOIN l10n l USING (l10n_id)
LEFT JOIN user_l10n ul ON (ul.l10n_id=l.l10n_id AND ul.user_id=$user_id)
WHERE cl.content_id IN ($list) AND c.description IS NOT NULL
ORDER BY content_id, COALESCE(ul.order,l.order)
) d GROUP BY content_id
)
USING (content_id)
关于php - 多语言 MySQL 内容 : how to select a given language or another if the one specified isn't available?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5919733/