[英]T-SQL (azure compatible) get values from one column as a row of data
[英]T-sql putting values of column into one row
假設我有下表
ClassID StudentID
1 10
1 11
2 12
2 10
3 13
我想要這樣的桌子
ClassID StudentID1 StudenID2 ... StudentID32
1 10 11 null
2 12 10 null
3 3 null null
有沒有一種方法可以查詢上表。 限制:每個班級最多可容納32名學生(可以是任何預定義的人數)。 我猜想while循環可以以某種方式使用,但是應該有其他方式。
編輯我嘗試使用Pivot,但是在那里我必須使用某種聚合,但是對於上述問題,我不必使用任何聚合。 在樞軸中,我必須為列命名(類似於in(col1, col2,...)
),但是在這里我什至不知道學生的ID。 有什么通用的方法可以解決上述簡單問題,以便每一行代表所有學生一個唯一的ClassID,其中每個StudentID在不同的列中(列可以根據您的喜好命名),但每個ClassID最多可以包含32個StudentID(我不應該使用自我聯接,因為這不切實際)
我希望我能清楚地理解您。.盡管如此,在這里我仍然使用PIVOT,我想我也不知道學生證。
create table Student (
ClassID INT
, StudentID INT
)
INSERT INTO Student (ClassID, StudentID) VALUES
(1,10)
, (1,11)
, (2,12)
, (2,10)
, (3,13)
select
'Student' + CONVERT(NVARCHAR(150),ROW_NUMBER () OVER (PARTITION BY ClassID ORDER BY StudentID)) AS StudentNo
, *
into #tmpStud
from Student
declare @distinct nvarchar(max) = ''
/*
option a : flexible to the number of students
*/
--set @distinct = (select distinct '[' + StudentNo + '],' as [text()] from #tmpStud for xml path(''))
--set @distinct = SUBSTRING(@distinct, 0, LEN(@distinct))
/*
option b : max of 32 student
*/
declare @max int = 33
, @loop int = 1
while (@loop < @max)
begin
if(@loop = 1) begin
set @distinct = @distinct + '[Student' + Convert(nvarchar(20),@loop) + ']'
set @loop = @loop + 1
end
else begin
set @distinct = @distinct + ',[Student' + Convert(nvarchar(20),@loop) + ']'
set @loop = @loop + 1
end
end
exec ('
select
*
from (
select
ClassID
, StudentNo
, StudentID
FROM #tmpStud
) AS s PIVOT
(
MAX(StudentID)
FOR StudentNo IN (' + @distinct + ')
) AS pvt
')
drop table #tmpStud
編輯:一旦您有創建表的學生,請運行以下代碼:
select
'Student' + CONVERT(NVARCHAR(150),ROW_NUMBER () OVER (PARTITION BY ClassID ORDER BY StudentID)) AS StudentNo
, *
into #tmpStud
from Student
declare @distinct nvarchar(max) = ''
/*
option a : flexible to the number of students
*/
set @distinct = (select distinct '[' + StudentNo + '],' as [text()] from #tmpStud for xml path(''))
set @distinct = SUBSTRING(@distinct, 0, LEN(@distinct))
exec ('
select
*
from (
select
ClassID
, StudentNo
, StudentID
FROM #tmpStud
) AS s PIVOT
(
MAX(StudentID)
FOR StudentNo IN (' + @distinct + ')
) AS pvt
')
drop table #tmpStud
編輯:假設您將需要32名學生的靜態@ max ..使用下面的腳本。
select
'Student' + CONVERT(NVARCHAR(150),ROW_NUMBER () OVER (PARTITION BY ClassID ORDER BY StudentID)) AS StudentNo
, *
into #tmpStud
from Student
declare @distinct nvarchar(max) = ''
/*
option b : static max of 32 student
*/
declare @max int = 33
, @loop int = 1
while (@loop < @max)
begin
if(@loop = 1) begin
set @distinct = @distinct + '[Student' + Convert(nvarchar(20),@loop) + ']'
set @loop = @loop + 1
end
else begin
set @distinct = @distinct + ',[Student' + Convert(nvarchar(20),@loop) + ']'
set @loop = @loop + 1
end
end
exec ('
select
*
from (
select
ClassID
, StudentNo
, StudentID
FROM #tmpStud
) AS s PIVOT
(
MAX(StudentID)
FOR StudentNo IN (' + @distinct + ')
) AS pvt
')
drop table #tmpStud
在已知的限制相對較小(例如10)的情況下,自連接將起作用。
(當發問者解釋為10並不是真正的限制時,刪除此答案)
您需要結合使用Count(),GROUP BY,臨時表和PIVOT函數。
對於上面的示例,我有以下內容,它似乎可以正常工作。 您可以修改數據透視圖以動態導出列名,但這需要一些思考。
WITH CTE
AS (SELECT ClassID,
COUNT(StudentID) AS StudentNum
FROM KamTest.dbo.Table1
GROUP BY ClassID)
SELECT A.ClassID,
B.StudentID,
A.StudentNum INTO #temp
FROM CTE AS A
INNER JOIN
KamTest.dbo.Table1 AS B
ON A.ClassID=B.ClassID;
SELECT ClassID,
MAX(StudentID),
COUNT(StudentID)
FROM KamTest.dbo.Table1
GROUP BY ClassID;
SELECT ClassID,
[10] AS StudentID10,
[11] AS StudentID11,
[12] AS StudentID12,
[13] AS StudentID13
FROM(
SELECT ClassID,
StudentID,
StudentNum
FROM #temp) AS SourceTable PIVOT(MAX(StudentNum) FOR StudentID IN([10],
[11],
[12],
[13])) AS PivotTable;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.