一种带过滤的交叉连接查询

时间:2016-11-02 21:40:46

标签: sql sql-server jointable

我有以下三个表:

dbo.Product
Id  | Name
1   | P1
2   | P2

dbo.ProductTranslations
Id  | LangId    | Text
1   | 1         | Text_EN
1   | 2         | Text_DE
2   | 1         | OtherText_EN

dbo.Language
Id  | Culture
1   | en-US
2   | de-DE
3   | es-ES

我需要一个类似的查询:

select * 
from ProductTranslations pt (some join) Language lang

生产: 对于产品1:

1   | en-US     | Text_EN
1   | de-DE     | Text_DE
1   | es-ES     | null
产品2的

2   | en-US     | OtherText_EN
2   | de-DE     | null
2   | es-ES     | null

理想情况下,我希望有一个可以使用Id过滤的视图。 任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:0)

SELECT
    p.Id
    ,p.Name
    ,l.Id as LangId
    ,l.Culture
    ,t.Text
FROM
    dbo.Product p
    CROSS JOIN dbo.Language l
    LEFT JOIN dbo.ProductTransalations t
    ON p.Id = t.Id
    AND l.Id = t.LangId

在产品和语言之间使用笛卡尔联接来获得它们的所有可能组合,然后左键加入ProductTranslations。

这是一个完整的工作示例

DECLARE @Product AS TABLE (Id INT, Name CHAR(2))
DECLARE @ProductTransalations AS TABLE (Id INT, LangId INT, Text VARCHAR(50))
DECLARE @Language AS TABLE (Id INT, Culture VARCHAR(20))

INSERT INTO @Product VALUES (1,'P1'),(2,'P2')
INSERT INTO @ProductTransalations VALUES (1,1,'Text_EN'),(1,2,'Text_DE'),(2,1,'OtherText_EN')
INSERT INTO @Language VALUES (1,'en-US'),(2,'de-DE'),(3,'es-ES')

SELECT
    p.Id
    ,p.Name
    ,l.Id as LangId
    ,l.Culture
    ,t.Text
FROM
    @Product p
    CROSS JOIN @Language l
    LEFT JOIN @ProductTransalations t
    ON p.Id = t.Id
    AND l.Id = t.LangId

答案 1 :(得分:0)

我明白了。您需要所有语言的行,即使没有匹配的翻译。

您可以使用left join

执行此操作
select p.productId, l.culture, pt.text
from (select 1 as productId) p cross join
     language l left join
     ProductTranslations pt
     on pt.id = p.productId and pt.langid = l.id;

您可以将“1”更改为您喜欢的任何产品。

如果您更喜欢使用where子句,则可以执行以下操作:

select p.productId, l.culture, pt.text
from product p cross join
     language l left join
     ProductTranslations pt
     on pt.id = p.productId and pt.langid = l.id
where p.id = 1;