4

我有一个这样的数据库结构:

SELECT * FROM Culture;
------------------------
Id  ShortName   FullName                Supported
22  en-US       English (United States) 1
23  fr-FR       French (France)         1
24  hi-IN       Hindi (India)           0

SELECT * FROM ResourceKey;
----------------------------
Id      Name
20572   HowAreYou
20571   Hello


SELECT * FROM Strings;
-----------------------
Id      CultureId   ResourceKeyId           ResourceValue
41133   22          20571                   Hello
41134   22          20572                   How are you?
41135   23          20571                   Bonjour
41136   23          20572                   Comment allez-vous?


SELECT * FROM Category;
------------------------
Id  Name
1   JavaScript


SELECT * FROM StringCategory;
------------------------------
Id  ResourceKeyId   CategoryId
1   20571           1
2   20572           1

我想要一个 SQL 查询给我以下结果:

Key         CategoryName    en-US               fr-FR                   another-SupportedCulture                        And so on
-------------------------------------------------------------------------------------------------------------------------------------------------------------
Hello       JavaScript      Hello               Bonjour                 Value of hello in that supported culture        and so on for all supported cultures
HowAreYou   JavaScript      How are you?        Comment allez-vous?     Value of HowAreYou in that supported culture    and so on for all supported cultures

我知道如何为个人文化编写查询。Culture我想我将为表中Supported字段设置为 1 ( true)的所有文化编写单独的查询。然后,我将在英语文化(将具有所有值)和所有其他文化之间应用 LEFT OUTER JOIN 以获得上述数据集。

到目前为止,我在编写针对单一文化的查询方面已经走到了这一步:

SELECT 
ResourceKey.Id AS ResourceKeyId, 
ResourceKey.Name AS [Key], 
Category.Name AS CategoryName, 
Culture.Id AS CultureId, 
Culture.ShortName AS CultureShortName, 
Strings.ResourceValue
FROM 
ResourceKey LEFT OUTER JOIN Strings ON ResourceKey.Id = Strings.ResourceKeyId
INNER JOIN Culture ON Strings.CultureId = Culture.Id
LEFT OUTER JOIN StringCategory ON ResourceKey.Id = StringCategory.ResourceKeyId
LEFT OUTER JOIN Category ON StringCategory.CategoryId = Category.Id
WHERE Strings.CultureId = 23; -- this will be a T-SQL stored procedure parameter I understand

它返回以下结果:

ResourceKeyId   Key         CategoryName    CultureId   CultureShortName    ResourceValue
----------------------------------------------------------------------------------
20571           Hello       JavaScript      23          fr-FR               Bonjour
20572           HowAreYou   JavaScript      23          fr-FR               Comment allez-vous?

问题是:我不确定如何在 T-SQL 中编写一个循环,然后将这些单独的数据集存储在临时内存区域中(我相信有一个术语,用于驻留在内存中的某些表类型表达式并且仅在 T-SQL 批处理期间,正是针对像我这样的情况)在 SQL 过程中,然后对它们应用连接。那就是我需要帮助的地方。

感谢您耐心阅读我的问题并提供帮助。

我正在使用 Microsoft SQL Server 2008 Express R2。

4

2 回答 2

1

如果要动态列数,则必须使用动态 SQL:

declare @stmt nvarchar(max)

select @stmt =
    isnull(@stmt + ', ', '') +
    'max(case when s.CultureId = ' + cast(c.Id as nvarchar(max)) +
    ' then s.ResourceValue end) as ' + quotename(c.ShortName)
from Culture as c
where c.Supported = 1

select @stmt = '
    select
        rk.Name as [Key],
        c.Name as CategoryName, ' + @stmt + '
    from StringCategory as sc
        inner join Category as c on c.Id = sc.CategoryId
        inner join ResourceKey as rk on rk.Id = sc.ResourceKeyId
        inner join Strings as s on s.ResourceKeyId = rk.Id
    group by rk.Name, c.Name
'

exec sp_executesql @stmt = @stmt;

sql fiddle demo

于 2013-09-11T13:43:51.037 回答
0

我从一位同事那里得知我需要在这里申请 PIVOT。T-SQL 和 SQL Server 2005 及更高版本支持 PIVOT 操作。以下是关于为什么 PIVOT 在上述情况下有用以及如何制作的一些链接:

http://blogs.msdn.com/b/spike/archive/2009/03/03/pivot-tables-in-sql-server-a-simple-sample.aspx

http://www.codeproject.com/Tips/500811/Simple-Way-To-Use-Pivot-In-SQL-Query

于 2013-09-11T13:15:13.767 回答