Sql server SQL扁平化翻译表

Sql server SQL扁平化翻译表,sql-server,join,pivot,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

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

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
我想做的基本上是将其展平,以便所有产品和翻译都在一个表中,并将每个产品压缩成一行,如下所示:

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
我已经翻遍了一些例子,比如关于旋转的例子,最好的建议性能方面似乎是使用大量的案例陈述,但我很难将它们应用到我的情况中。使用第二个链接中的case语句可以使翻译线性化,但不会减少项目总数。我正在处理4000万行,最终会处理十几个连接,因此速度非常关键,使用与所有这些数据不同的select会降低性能,我需要在select语句中对数据进行清理

这有什么我不知道的诀窍吗


编辑:我应该注意到,有时翻译后的描述中有真正的价值,当它是“EN-US”时,不要问为什么,我没有设计这个,这些需要覆盖原始描述,所以我不能只选择语言!='EN-US’或类似产品。还有更多的语言不仅仅是英语和法语,我只是为了演示而简化了它。

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

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,以提高翻译表中英文翻译的优先级-如果为空,则从products表中获取原始描述


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

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

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;
如果要创建表,可以添加到FlattedProducts中

联接方法是:

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';

这将返回所有产品。如果您知道每个产品至少有一个翻译,那么使用内部连接而不是完全连接-这样效率更高。

出于好奇,这里的GROUP BY语句的目的是什么?如果我忽略它,我会得到一个错误,但我不确定为什么必须从它开始。它将为每个组返回一行:ProductID。然后你只需要使用聚合函数,比如MAX,来指定你想要给定组的最大值,每种语言只有一个。这两个答案都很好,我希望我能接受这两个。谢谢你的帮助。