簡體   English   中英

T-sql將列的值放入一行

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM