SQL服务器:将行转置为列(n:m关系)

时间:2016-05-27 12:22:24

标签: sql sql-server pivot transpose

自己尝试了几个小时后,我需要寻求帮助。到目前为止我只做了一些基本的SQL。

我想解决以下问题:

(我已经翻译了几件事让你理解上下文)

我有三张桌子:

工人(德语中的Mitarbeiter - mitID)

| mitID | Name   | FamName | DOB        | abtIDref |
|-------|--------|---------|------------|----------|
| 1     | Frank  | Sinatra | 12.12.1915 | 1        |
| 2     | Robert | Downey  | 4.4.1965   | 2        |

信息:abtIDrefWorkplace的1:n关系,但此处不涉及

技能(Faehigkeiten in German - faeID)

| faeID | Descr | time | cost |
|-------|-------|------|------|
| 1     | HV    | 2    | 0    |
| 2     | PEV   | 1    | 0    |
| 3     | Drive | 8    | 250  |
| 4     | Nex   | 20   | 1200 |

链路列表

| linkID | mitIDref | feaIDref | when       |
|--------|----------|----------|------------|
| 1      | 2        | 1        | 27.07.2014 |
| 2      | 2        | 2        | 01.01.2016 |
| 3      | 2        | 3        | 20.01.2016 |
| 4      | 1        | 3        | 05.06.2015 |
| 5      | 1        | 4        | 02.11.2015 |

期望的结果是:

| mitID | Name   | FamName | DOB        | abtIDref | HV        | PEV        | Drive      | Nex        |
|-------|--------|---------|------------|----------|-----------|------------|------------|------------|
| 1     | Frank  | Sinatra | 12.12.1915 | 1        |           |            | 05.06.2015 | 02.11.2015 |
| 2     | Robert | Downey  | 4.4.1965   | 2        | 27.7.2014 | 01.01.2016 | 20.01.2015 |            |

替代方案可能是:

| mitID | Name   | FamName | DOB        | abtIDref | HV | PEV | Drive | Nex |
|-------|--------|---------|------------|----------|----|-----|-------|-----|
| 1     | Frank  | Sinatra | 12.12.1915 | 1        |    |     | x     | x   |
| 2     | Robert | Downey  | 4.4.1965   | 2        | x  | x   | x     |     |

目标是用户/管理员可以添加新技能,如果某人拥有此技能,则有人可以在此结果列表中查看。

我尝试了什么:

我遇到了动态SQL和pivot函数的多个示例,但我不知道如何在我的情况下使用它,因为我没有运行像AVG()或{{1这样的函数}}

我试过这样:

MIN()

第二种方法是:

DECLARE @columns AS VARCHAR(MAX);
DECLARE @sql AS VARCHAR(MAX);

select @columns = substring((Select DISTINCT ',' + QUOTENAME(faeID) FROM mdb_Fähigkeiten FOR XML PATH ('')),2, 1000);

SELECT @sql = 'SELECT * FROM mdb_Mitarbeiter
PIVOT 
(
    MAX(Value) 
    FOR mitID IN( ' + @columns + ' )
);';

execute(@sql);

但TBH我没有找到找到的功能。 我希望你能为我提供一些指导,我必须改变(或者即使我可以)实现这一目标。

1 个答案:

答案 0 :(得分:1)

我相信下面的查询就是你要找的。根据需要调整列名和表名以适合您的数据库。

DECLARE @sql AS NVARCHAR(MAX)
DECLARE @cols AS NVARCHAR(MAX)

SELECT @cols= ISNULL(@cols + ',','') + QUOTENAME(Descr)
FROM Faehigkeiten ORDER BY faeID 

SET @sql = N'
    SELECT mitID, Name, FamName, DOB, abtIDref, ' + @cols + '
    FROM (
       SELECT mitID, Name, FamName, DOB, abtIDref, [when], descr 
       FROM Mitarbeiter m
       JOIN [Link-List] l ON m.mitID = l.mitIDref
       JOIN Faehigkeiten f ON f.faeID = l.feaIDref
    ) a
    PIVOT(MAX([when]) FOR descr IN (' + @cols + ')) p'

EXEC sp_executesql @sql