首页 > 解决方案 > SQL 行列数据交换

问题描述

目前我正在构建一个工具来添加/更新翻译数据并为使用该数据的程序生成一个 XML 文件。

我读入 XML 文件并将其存储在数据库中,以便我们以后也可以使用这些数据来创建其他翻译文件。

为了将数据库中的数据导入工具,我根据大量可能的翻译(存储在不同的表中)生成 SQL 查询,并根据 ID 将它们与翻译数据连接起来。在工具内部,我使用了一个 dataTable,为此我试图将 rowdata 动态交换到一列。这应该很容易,但我正在努力解决。

有两张表,一张包含语言环境,一张包含数据。

[dbo].[Locales]
    [Id] [int] IDENTITY(1,1) NOT NULL
    [Locale] [nvarchar](10) NOT NULL

[dbo].[Translations]
    [Id] [int] IDENTITY(1,1) NOT NULL
    [TranslationID] [int] NOT NULL
    [Text] [nvarchar](max) NULL
    [LocaleID] [int] NOT NULL

翻译数据如下所示:

翻译ID 文本 语言环境
1 连接体 es_ES
1 Anschlüsse de_DE
1 连接点 zh_CN
1 安斯吕廷根 nl_NL
2 跨界组织 de_DE
2 电源 zh_CN

我想要它:

翻译ID nl_NL zh_CN de_DE es_ES x_X
1 安斯吕廷根 连接点 Anschlüsse 连接体 无效的
2 投票 电源 跨界组织 无效的 某种语言

我试图使用 LEFT JOIN 和 OUTER JOIN 来获取数据,但没有成功。问题是并非所有翻译数据都可用(这就是为其构建工具的原因)。我也找到了“PIVOT”,但它看起来无法生成我想要的数据,因为 PIVOT 需要一个聚合函数。

提前致谢!

标签: c#sqljoindynamicpivot

解决方案


如果你不想使用 PIVOT,你可以得到唯一的 translationID 列表:

SELECT TranslationID
FROM Translations
GROUP BY TranslationID

然后使用子查询获取各个语言环境(为了简洁起见,我在其中添加了一个Locale列):Translations

SELECT
    UniqueTID,
    (SELECT Text FROM Translations t WHERE (TranslationID = UniqueTID AND Locale = 'nl_NL') as nl_NL,
    (SELECT Text FROM Translations t WHERE (TranslationID = UniqueTID AND Locale = 'en_US') as en_US,
    (SELECT Text FROM Translations t WHERE (TranslationID = UniqueTID AND Locale = 'de_DE') as de_DE
FROM (
    SELECT TranslationID as UniqueTID
    FROM Translations
    GROUP BY TranslationID
) uniqTIDs

或使用外部连接:

SELECT
    UniqueTID,
    nlTrans.Text as nl_NL,
    enTrans.Text as en_US,
    deTrans.Text as de_DE
FROM (
    SELECT TranslationID as UniqueTID
    FROM Translations
    GROUP BY TranslationID
) uniqueTIDs
    LEFT JOIN Translations nlTrans ON (nlTrans.TranslationID = UniqueTID AND nlTrans.Locale = 'nl_NL')
    LEFT JOIN Translations enTrans ON (enTrans.TranslationID = UniqueTID AND enTrans.Locale = 'en_US')
    LEFT JOIN Translations deTrans ON (deTrans.TranslationID = UniqueTID AND deTrans.Locale = 'de_DE')

推荐阅读