我正在处理一组类似于以下内容的数据。
StudentName | AssignmentName | Grade --------------------------------------- StudentA | Assignment 1 | 100 StudentA | Assignment 2 | 80 StudentA | Total | 180 StudentB | Assignment 1 | 100 StudentB | Assignment 2 | 80 StudentB | Assignment 3 | 100 StudentB | Total | 280
作业的名称和数量是动态的,我需要将结果与以下内容相似。
Student | Assignment 1 | Assignment 2 | Assignment 3 | Total -------------------------------------------------------------------- Student A | 100 | 80 | null | 180 Student B | 100 | 80 | 100 | 280
现在理想情况下,我希望根据可能包含/关联每个作业的“截止日期”对列进行排序。如果可能,总数应该在最后(如果可能,可以计算并从查询中删除。)
我知道如何通过简单地命名列来使用数据透视表进行3次分配,它正试图以动态的方式进行,我还没有找到好的解决方案。我试图在SQL Server 2005上执行此操作
修改
理想情况下,我希望在不使用动态SQL的情况下实现此功能,因为这违反了策略。如果不可能......那么使用动态SQL的工作示例将起作用。
答案 0 :(得分:12)
我知道你说没有动态SQL
,但我认为没有办法直接SQL
。
如果您在Pivot Table and Concatenate Columns和PIVOT in sql 2005
查看我对类似问题的回答动态SQL
不易受到注射,并且没有充分理由禁止注射。另一种可能性(如果数据很少变化)是代码生成 - 而不是动态SQL
,SQL
定期生成存储过程。
答案 1 :(得分:8)
使用动态SQL将PIVOT
这些数据添加到SQL Server 2005 +中可以使用以下代码:
创建表格
CREATE TABLE yourtable
([StudentName] varchar(8), [AssignmentName] varchar(12), [Grade] int)
;
INSERT INTO yourtable
([StudentName], [AssignmentName], [Grade])
VALUES
('StudentA', 'Assignment 1', 100),
('StudentA', 'Assignment 2', 80),
('StudentA', 'Total', 180),
('StudentB', 'Assignment 1', 100),
('StudentB', 'Assignment 2', 80),
('StudentB', 'Assignment 3', 100),
('StudentB', 'Total', 280)
;
动态PIVOT:
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT distinct ',' + QUOTENAME(AssignmentName)
from yourtable
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT StudentName, ' + @cols + ' from
(
select StudentName, AssignmentName, grade
from yourtable
) x
pivot
(
min(grade)
for assignmentname in (' + @cols + ')
) p '
execute(@query)
结果是:
| STUDENTNAME | ASSIGNMENT 1 | ASSIGNMENT 2 | ASSIGNMENT 3 | TOTAL |
--------------------------------------------------------------------
| StudentA | 100 | 80 | (null) | 180 |
| StudentB | 100 | 80 | 100 | 280 |
答案 2 :(得分:1)
我发现这样做的唯一方法是使用动态SQL并将列标签放入变量中。
答案 3 :(得分:0)
您可以查询information_schema以获取列名称和类型,然后在构建结果集时将结果用作子查询。请注意,您可能需要稍微更改登录的访问权限。
答案 4 :(得分:0)
如果此数据用于报告中,则可以使用SSRS矩阵。它将从结果集动态生成列。我已多次使用它 - 它对动态交叉表报告非常有用。
这是w / dynamic sql的一个很好的例子。 http://www.simple-talk.com/community/blogs/andras/archive/2007/09/14/37265.aspx
答案 5 :(得分:-1)
SELECT TrnType
INTO #Temp1
FROM
(
SELECT '[' + CAST(TransactionType AS VARCHAR(4)) + ']' AS TrnType FROM tblPaymentTransactionTypes
) AS tbl1
SELECT * FROM #Temp1
SELECT * FROM
(
SELECT FirstName + ' ' + LastName AS Patient, TransactionType, ISNULL(PostedAmount, 0) AS PostedAmount
FROM tblPaymentTransactions
INNER JOIN emr_PatientDetails ON tblPaymentTransactions.PracticeID = emr_PatientDetails.PracticeId
INNER JOIN tblPaymentTransactionDetails ON emr_PatientDetails.PatientId = tblPaymentTransactionDetails.PatientID
AND tblPaymentTransactions.TransactionID = tblPaymentTransactionDetails.TransactionID
WHERE emr_PatientDetails.PracticeID = 152
) tbl
PIVOT (SUM(PostedAmount) FOR [TransactionType] IN (SELECT * FROM #Temp1)
) AS tbl4
答案 6 :(得分:-2)
select studentname,[Assign1],[Assign2],[Assign3],[Total]
from
(
select studentname, assignname, grade from student
)s
pivot(sum(Grade) for assignname IN([Assign1],[Assign2],[Assign3],[Total])) as pvt