알 수없는 수의 열에 대한 SQL Server 2005 피벗
-
03-07-2019 - |
문제
다음과 같은 모습을 보이는 데이터 세트로 작업하고 있습니다.
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
이제 이상적으로는 각 할당과 관련/관련 될 수있는 "기한"을 기준으로 열을 정렬하고 싶습니다. 가능한 경우 총계가 끝나야합니다 (가능한 경우 쿼리에서 계산 및 제거 할 수 있습니다.)
나는 단순히 열을 단순히 이름을 지정하는 Pivot을 사용하여 3 가지 과제를 위해 그것을하는 방법을 알고 있습니다. 그것은 아직 좋은 솔루션을 찾지 못한 역동적 인 방식으로 그것을 시도하고 있습니다. SQL Server 2005 에서이 작업을 수행하려고합니다.
편집하다
이상적으로는 동적 SQL을 사용하지 않고이를 구현하고 싶습니다. 가능하지 않은 경우 ... 동적 SQL을 사용하는 작업 예제가 작동합니다.
해결책
나는 당신이 역동적 인 말하지 않았다는 것을 알고 있습니다 SQL
,하지만 나는 그것을 똑바로 할 방법이 없다 SQL
.
비슷한 문제에 대한 내 답을 확인하면 피벗 테이블 및 연결 열 그리고 SQL 2005의 피벗
역학 SQL
주사에 취약하지 않으며이를 금지할만한 이유는 없습니다. 또 다른 가능성 (데이터가 매우 드물게 변하는 경우)은 동적 대신 코드 생성을 수행하는 것입니다. SQL
,, SQL
정기적으로 저장 절차로 생성됩니다.
다른 팁
에게 PIVOT
동적 SQL을 사용한이 데이터는 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)
;
동적 피벗 :
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 |
내가 이것을하는 유일한 방법은 동적 SQL을 사용하고 열 레이블을 변수에 넣는 것입니다.
information_schema를 쿼리하여 열 이름과 유형을 얻은 다음 결과 세트를 빌드 할 때 결과를 하위 쿼리로 사용할 수 있습니다. 기록 로그인의 액세스를 약간 변경해야 할 것입니다.
이것은 동일합니다 SQL 2005의 피벗
이 데이터가 보고서에서 소비되는 경우 SSRS 매트릭스를 사용할 수 있습니다. 결과 세트에서 열을 동적으로 생성합니다. 나는 그것을 여러 번 사용했습니다 - 그것은 Dynamic CrosStab 보고서에 매우 효과적입니다.
다음은 동적 SQL과 좋은 예입니다.http://www.simple-talk.com/community/blogs/andras/archive/2007/09/14/37265.aspx
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
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