子查询的结果为列

时间:2013-08-14 07:08:30

标签: sql sql-server sql-server-2008-r2

我有一张带有一些术语的表格。这些术语有多种语言。例如:

SELECT *
FROM Terminology

结果

ID   language          text        create_date
1       DE          TextDE  2011-03-03 14:31:28.423
1       EN          TextEN  2011-04-03 14:32:27.423
1       ES          TextES  2011-05-03 14:33:26.423
1       FR          TextFR  2011-06-03 14:34:25.423
1       NL          TextNL  2011-07-03 14:35:24.423
1       PT          TextPT  2011-08-03 14:36:23.423
2       DE                 ...
...

但我需要以下形式的数据:

ID  DE     EN     ES     FR     NL     PT
1 TextDE TextEN TextES TextFR TEXTNL TextPT
2 ...

IDlanguage正在构建主键。语言的数量是可变的,因此不可能只添加6个额外的列。

以某种方式可以使用普通的SQL查询来完成这项工作,还是我必须在我的程序中对此进行排序?

修改
如果表中的列未选中,但具有不同的值,则会得到多行 因此,在具有6个不同日期的示例中,我得到6个不同的行:

ID          DE         EN         ES         FR         NL         PT

1   TextDE            NULL       NULL       NULL       NULL       NULL
1   NULL              TextEN     NULL       NULL       NULL       NULL
1   NULL              NULL       TextES     NULL       NULL       NULL
1   NULL    NULL    NULL    TextFr NULL NULL    NULL
...

我可以以某种方式将其转为一行吗?

2 个答案:

答案 0 :(得分:3)

试试这个 -

IF OBJECT_ID (N'tempdb.dbo.#temp') IS NOT NULL
   DROP TABLE #temp

CREATE TABLE #temp (
      ID INT
    , [language] CHAR(2)
    , [text] VARCHAR(10)
    , create_date DATETIME
)
INSERT INTO #temp (ID, [language], [text], create_date)
VALUES 
    (1, 'DE', 'TextDE', '2011-03-03 14:31:28.423'),
    (1, 'EN', 'TextEN', '2011-04-03 14:32:27.423'),
    (1, 'ES', 'TextES', '2011-05-03 14:33:26.423'),
    (1, 'FR', 'TextFR', '2011-06-03 14:34:25.423'),
    (1, 'NL', 'TextNL', '2011-07-03 14:35:24.423'),
    (1, 'PT', 'TextPT', '2011-08-03 14:36:23.423'),
    (2, 'PT', 'TextPT', NULL)

DECLARE @SQL NVARCHAR(MAX)
SELECT @SQL = '
    SELECT ID, DE, EN, ES, FR, NL, PT
    FROM (
        SELECT ID, [language], [text]
        FROM #temp
    ) t
    PIVOT (
        MAX([text]) 
        FOR [language] IN (' + 
        STUFF((
            SELECT DISTINCT ', [' + t.[language] + ']'
            FROM #temp t
            FOR XML PATH(''), TYPE).value('.', 'VARCHAR(MAX)'), 1, 2, '') + ')
    ) pv'

PRINT @SQL
EXEC sys.sp_executesql @SQL

输出 -

ID          DE         EN         ES         FR         NL         PT
----------- ---------- ---------- ---------- ---------- ---------- ----------
1           TextDE     TextEN     TextES     TextFR     TextNL     TextPT
2           NULL       NULL       NULL       NULL       NULL       TextPT

答案 1 :(得分:1)

在SQL Server中没有简单的方法可以做到这一点,请参阅此答案以获取一般解决方案 - https://stackoverflow.com/a/13583258/1744834

您可以执行少量列:

select
    ID,
    max(case when language = 'DE' then text else null end) as TextDE,
    max(case when language = 'EN' then text else null end) as TextEN,
    ...
from Terminology
group by ID