情况:
我有主表,我们称之为MainTable
。
+---------+----------+----------+----------+
| Id (PK)| Title | Text | Type |
+---------+----------+----------+----------+
| 1 | Some Text|More Stuff| A |
| 2 | Another | Example | B |
+---------+----------+----------+----------+
我有一个名为TranslationsTable
的第二个表,其中Id字段是MainTable
行Id的表示(没有外键,因为它可以引用不同的表),ObjType是ObjectType(与表相同),FieldName是ObjecType中字段的名称,值具有ObjType表中FieldName值的转换值。
+---------+-----------+-----------+------------+----------+
| Id | ObjType | FieldName | Value | Language |
+---------+-----------+-----------+------------+----------+
| 1 | MainTable | Title | Algum Texto| PT |
| 1 | MainTable | Text | Mais Coisas| PT |
+---------+-----------+-----------+------------+----------+
因为我需要在翻译的字段中搜索,我想我可以使用TEMPORARY TABLE
这样做,但后来出现了“我应该使用哪个SELECT查询?”的问题。我读了一些关于数据透视表查询的帖子,但我真的不知道我如何构建一个查询,所以我的临时表类似于
+---------+------------+------------+----------+
| Id (PK)| Field_1 | Field_2 | Field_3 |
+---------+------------+------------+----------+
| 1 | Algum Texto| Mais Coisas| A |
+---------+------------+------------+----------+
谢谢。
编辑:
我接受了AD7six的答案,因为在MainTable中有500.000个条目,在翻译中有1.500.000个条目,它大约是另一个条目的30倍。
答案 0 :(得分:2)
SELECT
orig.Id,
COALESCE(xlate.Field_1, orig.Field_1) AS Field_1,
COALESCE(xlate.Field_2, orig.Field_2) AS Field_2,
COALESCE(xlate.Field_3, orig.Field_3) AS Field_3
FROM MainTable orig
INNER JOIN (
SELECT
Id,Field_1,Field_2,Field_3
FROM TranslationsTable
PIVOT(MIN(Value) FOR FieldName IN (Field_1,Field_2,Field_3)) p
WHERE ObjType = 'MainTable'
) xlate ON (orig.Id = xlate.Id)
如果要在MainTable中包含TranslationsTable中没有匹配项的(未翻译的)行,请将INNER JOIN更改为LEFT OUTER JOIN
另一种方法是手动执行转轴:
SELECT
orig.Id,
COALESCE(xlate.Field_1, orig.Field_1) AS Field_1,
COALESCE(xlate.Field_2, orig.Field_2) AS Field_2,
COALESCE(xlate.Field_3, orig.Field_3) AS Field_3
FROM MainTable orig
INNER JOIN (
SELECT
Id,
MIN(CASE FieldName WHEN 'Field_1' THEN Value END) AS Field_1,
MIN(CASE FieldName WHEN 'Field_2' THEN Value END) AS Field_2,
MIN(CASE FieldName WHEN 'Field_3' THEN Value END) AS Field_3
FROM TranslationsTable
WHERE ObjType = 'MainTable'
GROUP BY Id
) xlate ON (orig.Id = xlate.Id)
如其他人建议的那样更改MainTable架构,您将不需要重复(Field_1,Field_2,Field_3)。它使代码更易于维护和修改。
答案 1 :(得分:1)
这只是一个每个翻译字段有一个连接的查询。
这意味着您可以查询/排序/任何其他任何其他内容,例如(使用一些真实姓名,以便更容易阅读):
SELECT
products.id,
COALESCE(product_name.value, products.name) as name,
COALESCE(product_description.value, products.description) as description
FROM
products
LEFT JOIN
TranslationsTable AS product_name
ON (
product_name.Language = 'PT' AND
product_name.ObjectType = 'products' AND
product_name.FieldName = 'name' AND
product_name.id = products.id
)
LEFT JOIN
TranslationsTable AS product_description
ON (
product_description.Language = 'PT' AND
product_description.ObjectType = 'products' AND
product_description.FieldName = 'description' AND
product_description.id = products.id
)
WHERE
product_name.value = "Algum Texto" // Find all products named "Algum Texto"
但是如果你想创建一个,使用查询本身很容易:
CREATE TABLE
products_pt
AS
SELECT
products.id,
COALESCE(product_name.value, products.name) as name,
COALESCE(product_description.value, products.description) as description
...
这将创建一个与查询结构匹配的表(无索引)。如果您的数据不经常更改,则可以使查询多语言数据更容易管理,但有一些缺点,例如(显然)如果源表数据发生更改,您的特定于翻译的表将不是最新的。