SQL展平翻译表

时间:2016-10-04 21:36:15

标签: sql-server join pivot

我有一个产品表和一个单独的表,其中列出了这些产品的各种翻译。基本设置如下所示:

dbo.Products
ProductID | Description
1         | An amazing product
2         | An even more amazing product
3         | Don't buy this one

dbo.ProductTranslations
ProductID | Language | Description
1         | EN-US    | null
1         | FR-CA    | Un produit étonnant
2         | EN-US    | null
2         | FR-CA    | Un produit encore plus étonnant
3         | EN-US    | null
3         | FR-CA    | Ne pas acheter celui-ci

我想做的事情基本上是扁平化,所以所有的产品和翻译都放在一个表格中,并为每个产品压缩成一行,如下所示:

dbo.FlattenedProducts
ProductID | EN-US_Description            | FR-CA_Description
1         | An amazing product           | Un produit étonnant
2         | An even more amazing product | Un produit encore plus étonnant
3         | Don't buy this one           | Ne pas acheter celui-ci

我已经挖掘了像this one这样的关于旋转的示例和this one,其中最好的建议(性能方面)似乎使用了大量的案例陈述,但我很难应用它们对我的情况。使用类似于第二个链接的案例语句可以使翻译成为线性,但不会减少项目的总数。我正在使用4000万行(最终有十几个连接),因此速度至关重要,并且使用与所有这些数据不同的选择只会杀死性能,我需要将数据清除到select语句之外。< / p>

我有什么诀窍吗?

编辑:我应该注意,有时在翻译的描述中存在真正的值,当它是'EN-US'时(不要问为什么,我没有设计这个),那些需要覆盖原始描述,所以我不能只是SELECT WHERE Language != 'EN-US'或类似的。还有更多的语言,而不仅仅是英语和法语,我只是为了演示而简化它。

2 个答案:

答案 0 :(得分:1)

您似乎需要从产品表中返回英语说明。使用条件和聚合:

SELECT
  p.ProductID,
  MAX(CASE WHEN pt.Language = 'EN-US' THEN COALESCE(pt.Description, p.Description) END) AS ENUS_Description,
  MAX(CASE WHEN pt.Language = 'FR-CA' THEN pt.Description END) AS FRCA_Description
FROM dbo.Products p
LEFT JOIN dbo.ProductTranslations pt ON p.ProoductID = pt.ProductID 
GROUP BY p.ProductID

编辑:根据您的修改添加了COALESCE(),以便从翻译表中为英语翻译提供更高的优先级 - 如果它为空,则从产品表中获取原始描述。

对于更多语言,只需添加与FR-CA类似但具有不同语言值的相应行。

答案 1 :(得分:1)

最简单,最快的是条件聚合或连接:

select pt.productid,
       max(case when language = 'EN-US' then description end) as en_us,
       max(case when language = 'CA-FR' then description end) as ca_fr
from ProductTranslations pt
group by productid;

如果要创建表格,可以添加into FlattenedProducts

join方法是:

select coalesce(pte.productid, ptf.productid) as productid,
       pte.description as us_en,
       ptf.description as ca_fr
from ProductTranslations pte full join
     ProductTranslations ptf
     on pte.productid = ptf.productid and
        pte.language = 'EN-US' and ptf.language = 'CA-FR';

这将返回所有产品。如果您知道每个产品至少有一个翻译,那么使用inner join而不是full join - 它会更有效。