想象一下这样一种情况,我希望根据[FormValues]
的{{1}}列作为标题,将[Title]
的动态报告作为数据。
我真的很困惑该怎么做并尝试了很多方法,但没有一个能正常工作。
我应该能够给一个程序一个[ReportID]并得到结果。
[ReportItems]
和[FormID]
是两个表之间的关系键。
任何帮助都将受到高度赞赏。
[FieldID]
我想要这样的结果报告:
CREATE TABLE #ReportItems(
ReportItemID [uniqueidentifier] NOT NULL primary key,
ReportID [uniqueidentifier] NOT NULL,
FormID [uniqueidentifier] NOT NULL,
FieldID [uniqueidentifier] NOT NULL,
Title nvarchar(100) NOT NULL
)
GO
insert into #ReportItems
select '5674d274-b146-4251-be0d-a15000e7cefa', '597d37c0-563b-42f0-99be-a15000dc7a65', '01304636-fabe-4a3e-9487-a14b012f9a61', 'ba6b9b1a-92ef-4905-830a-a15000d05f7a', 'First Name'
insert into #ReportItems
select '5674d274-b146-4252-be0d-a15000e7cefa', '597d37c0-563b-42f0-99be-a15000dc7a65', '01304636-fabe-4a3e-9487-a14b012f9a61', 'ba6b9b1a-92ef-4905-830a-a15000d05f7b', 'Last Name'
insert into #ReportItems
select '5674d274-b146-4253-be0d-a15000e7cefa', '597d37c0-563b-42f0-99be-a15000dc7a65', '01304636-fabe-4a3e-9487-a14b012f9a61', 'ba6b9b1a-92ef-4905-830a-a15000d05f7c', 'Age'
GO
CREATE TABLE #FormValues(
ValueID uniqueidentifier NOT NULL primary key,
FormID uniqueidentifier NULL,
FieldID uniqueidentifier NOT NULL,
UserName nvarchar(100) NOT NULL,
Value nvarchar(max) null
)
GO
insert into #FormValues
select 'af6dc400-3972-49ff-9711-a1520002359e', '01304636-fabe-4a3e-9487-a14b012f9a61', 'ba6b9b1a-92ef-4905-830a-a15000d05f7a', 'user 1', 'Mike'
insert into #FormValues
select 'af6dc400-3972-49ff-9721-a1520002359e', '01304636-fabe-4a3e-9487-a14b012f9a61', 'ba6b9b1a-92ef-4905-830a-a15000d05f7b', 'user 1', 'Oscar'
insert into #FormValues
select 'af6dc400-3972-49ff-9731-a1520002359e', '01304636-fabe-4a3e-9487-a14b012f9a61', 'ba6b9b1a-92ef-4905-830a-a15000d05f7c', 'user 1', '20'
insert into #FormValues
select 'af6dc400-3972-49ff-9741-a1520002359e', '01304636-fabe-4a3e-9487-a14b012f9a61', 'ba6b9b1a-92ef-4905-830a-a15000d05f7a', 'user 2', 'Merry'
insert into #FormValues
select 'af6dc400-3972-49ff-9761-a1520002359e', '01304636-fabe-4a3e-9487-a14b012f9a61', 'ba6b9b1a-92ef-4905-830a-a15000d05f7c', 'user 2', '23'
insert into #FormValues
select 'af6dc400-3972-49ff-9771-a1520002359e', '01304636-fabe-4a3e-9487-a14b012f9a61', 'ba6b9b1a-92ef-4905-830a-a15000d05f7a', 'user 3', 'Alen'
insert into #FormValues
select 'af6dc400-3972-49ff-9781-a1520002359e', '01304636-fabe-4a3e-9487-a14b012f9a61', 'ba6b9b1a-92ef-4905-830a-a15000d05f7b', 'user 3', 'Escott'
insert into #FormValues
select 'af6dc400-3972-49ff-9791-a1520002359e', '01304636-fabe-4a3e-9487-a14b012f9a61', 'ba6b9b1a-92ef-4905-830a-a15000d05f7c', 'user 3', '28'
GO
Select * from #ReportItems
Select * from #FormValues
GO
答案 0 :(得分:3)
要获得所需的结果,您需要使用PIVOT
功能。
如果您的所有值(title
)都是提前知道的,那么您可以对静态查询进行硬编码:
select *
from
(
select r.Title, f.UserName, f.Value
from ReportItems r
left join FormValues f
on r.FormID = f.FormID
and r.FieldID = f.FieldID
) src
pivot
(
max(value)
for title in ([First Name], [Last Name], Age)
) piv;
但听起来你想要变成列的未知数量titles
。如果是这种情况,那么您将需要使用动态sql:
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT distinct ',' + QUOTENAME(Title)
from ReportItems
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT UserName,' + @cols + ' from
(
select r.Title, f.UserName, f.Value
from ReportItems r
left join FormValues f
on r.FormID = f.FormID
and r.FieldID = f.FieldID
) x
pivot
(
max(value)
for Title in (' + @cols + ')
) p '
execute(@query)
两者的结果将是:
| USERNAME | FIRST NAME | LAST NAME | AGE |
-------------------------------------------
| user 1 | Mike | Oscar | 20 |
| user 2 | Merry | (null) | 23 |
| user 3 | Alen | Escott | 28 |
如果您有一个特定的SortOrder
,并且将它存储在一个表中,那么当您获得列的列表时,您将使用以下内容,它将以正确的顺序返回列:
select @cols = STUFF((SELECT ',' + QUOTENAME(Title)
from ReportItems
group by Title, sortorder
order by sortorder
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
答案 1 :(得分:1)
DECLARE @SQL NVARCHAR(MAX)
SET @SQL='SELECT F.UserName'
SELECT @SQL = @SQL+', MAX(CASE WHEN FieldID='''+CONVERT(VARCHAR(50), FieldID)+''' THEN F.Value END) AS ['+Title+']
'
FROM #ReportItems
SET @SQL = @SQL+' FROM #FormValues F GROUP BY F.UserName ORDER BY 1'
--select @sql
EXEC sp_ExecuteSQL @SQL
稍后编辑:基于报告ID和排序列的报告程序
CREATE PROCEDURE spReport
@ReportID uniqueidentifier,
@SortColumns NVARCHAR(MAX) --shoud be a comma separated list of ReportItems.Title
AS
BEGIN
DECLARE @SQL NVARCHAR(MAX)
SET @SQL='SELECT F.UserName'
SELECT @SQL = @SQL+', MAX(CASE WHEN F.FieldID='''+CONVERT(VARCHAR(50), FieldID)+''' THEN F.Value END) AS ['+Title+']
'
FROM ReportItems
WHERE ReportID=@ReportID --create the dynamic sql only for the items in your report
SET @SQL = @SQL+' FROM FormValues F
JOIN ReportItems R ON F.FormID=R.FormID
WHERE R.ReportID = @ReportID
GROUP BY F.UserName '
IF @SortColumns<>''
SET @SQL = @SQL + 'ORDER BY '+@SortColumns -- beware of SQL injection.
select @sql
EXEC sp_ExecuteSQL @SQL, N'@ReportID uniqueidentifier', @ReportID=@ReportID
END
但是,我不能强调这一点,你必须特别注意当时的@SortColumns参数,因为你正在打开自己的SQL注入。