SQL 服务器:将行转列(n:m 关系)
SQL server: Transpose Rows to Columns (n:m relationship)
在自己尝试了几个小时之后,我现在需要寻求帮助。到目前为止,我只做了一些基本的 SQL。
我想解决以下问题:
(我翻译了一些内容,以便您了解上下文)
我有三个表:
工人(德语中的 Mitarbeiter - mitID)
| mitID | Name | FamName | DOB | abtIDref |
|-------|--------|---------|------------|----------|
| 1 | Frank | Sinatra | 12.12.1915 | 1 |
| 2 | Robert | Downey | 4.4.1965 | 2 |
信息:abtIDref
是 Workplace
的 1:n 关系,但此处未涉及
技能(德语中的 Faehigkeiten - faeID)
| faeID | Descr | time | cost |
|-------|-------|------|------|
| 1 | HV | 2 | 0 |
| 2 | PEV | 1 | 0 |
| 3 | Drive | 8 | 250 |
| 4 | Nex | 20 | 1200 |
Link-列表
| 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 | |
目标是 users/admins 可以添加新技能,并且有人可以在这个结果列表上看到,如果一个人有这个技能。
我尝试了什么:
我遇到过多个动态 SQL 和数据透视函数的示例,但我不知道如何在我的案例中使用它,因为我没有 运行 函数像 AVG()
或 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);
第二种方法是:
declare @collist nvarchar(max)
SET @collist = stuff((select distinct ',' + QUOTENAME(Question)
FROM #t1 -- your table here
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'),1,1,'')
select @collist
declare @q nvarchar(max)
set @q = '
select *
from (
select
Vorname, Bezeichnung, faeIDref
from (
select #t1.*, #t2.Answer, #t2.parent
from #t1
inner join #t2 on #t1.QID = #t2.QID
) as x
) as source
pivot (
max(Answer)
for Question in (' + @collist + ')
) as pvt
'
exec (@q)
但是老实说我没有找到函数。
我希望你能为我提供一些指导,我必须改变(或者即使我可以)实现这一目标。
我相信下面的查询就是您要查找的内容。根据需要调整列和 table 名称以适合您的数据库。
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
在自己尝试了几个小时之后,我现在需要寻求帮助。到目前为止,我只做了一些基本的 SQL。
我想解决以下问题:
(我翻译了一些内容,以便您了解上下文)
我有三个表:
工人(德语中的 Mitarbeiter - mitID)
| mitID | Name | FamName | DOB | abtIDref |
|-------|--------|---------|------------|----------|
| 1 | Frank | Sinatra | 12.12.1915 | 1 |
| 2 | Robert | Downey | 4.4.1965 | 2 |
信息:abtIDref
是 Workplace
的 1:n 关系,但此处未涉及
技能(德语中的 Faehigkeiten - faeID)
| faeID | Descr | time | cost |
|-------|-------|------|------|
| 1 | HV | 2 | 0 |
| 2 | PEV | 1 | 0 |
| 3 | Drive | 8 | 250 |
| 4 | Nex | 20 | 1200 |
Link-列表
| 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 | |
目标是 users/admins 可以添加新技能,并且有人可以在这个结果列表上看到,如果一个人有这个技能。
我尝试了什么:
我遇到过多个动态 SQL 和数据透视函数的示例,但我不知道如何在我的案例中使用它,因为我没有 运行 函数像 AVG()
或 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);
第二种方法是:
declare @collist nvarchar(max)
SET @collist = stuff((select distinct ',' + QUOTENAME(Question)
FROM #t1 -- your table here
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'),1,1,'')
select @collist
declare @q nvarchar(max)
set @q = '
select *
from (
select
Vorname, Bezeichnung, faeIDref
from (
select #t1.*, #t2.Answer, #t2.parent
from #t1
inner join #t2 on #t1.QID = #t2.QID
) as x
) as source
pivot (
max(Answer)
for Question in (' + @collist + ')
) as pvt
'
exec (@q)
但是老实说我没有找到函数。 我希望你能为我提供一些指导,我必须改变(或者即使我可以)实现这一目标。
我相信下面的查询就是您要查找的内容。根据需要调整列和 table 名称以适合您的数据库。
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