SQL将两行或多行合并为一行

时间:2011-01-28 23:02:35

标签: sql tsql

想象一下学生和多位教授 一位教授有很多学生 学生们在同一时间和日期上课。

表1

ClassName  | ProfessorName |StudentsPresent|ClassStartTime    |ClassDate  |ClassID
Philosophy | Stewart       |10             |8:00              |01/29/2011 | 1
Philosophy | Kyle          |10             |8:00              |01/29/2011 | 1
Religion   | Myke          |11             |8:30              |01/29/2011 | 2
Religion   | Nancy         |11             |8:30              |01/29/2011 | 2

我如何获得以下结果

ClassName  | ProfessorName |StudentsPresent|ClassStartTime    |ClassDate  |ClassID
Philosophy | Stewart,Kyle  |10             |8:00              |01/29/2011 | 1
Religion   | Myke,Nancy    |11             |8:30              |01/29/2011 | 2

正如我们所说,我正在研究游标。

2 个答案:

答案 0 :(得分:2)

你的桌子似乎非常规范化了。我听说游标在SQL Server中是一个可怕的东西,如果可以的话应该避免。有了它,把它放在一个名为Schedule的表中,这就是我可以满足你的要求的方式。

DECLARE @Schedule TABLE
(
    ClassName VARCHAR(50)
    , ProfessorName VARCHAR(50)
    , StudentsPresent INT
    , ClassStartTime TIME
    , ClassDate DATE
    , ClassID INT
);

INSERT INTO @Schedule
VALUES ('Philosophy', 'Stewart', 10, '8:00', '20110129', 1)
    , ('Philosophy', 'Kyle', 10, '8:00', '20110129', 1)
    , ('Religion', 'Myke', 11, '8:30', '20110129', 2)
    , ('Religion', 'Nancy', 11, '8:30', '20110129', 2);

WITH UniqueClasses AS
(
    SELECT DISTINCT
        ClassName
        , ClassStartTime
        , StudentsPresent
        , ClassDate
        , ClassID
    FROM @Schedule
)
SELECT
    ClassName
    ,   (
            STUFF((
                    SELECT
                        ',' + ProfessorName
                    FROM @Schedule Schedule
                    WHERE Schedule.ClassID = UniqueClasses.ClassID
                    FOR XML PATH('')
                ) , 1, 1, '')
        )AS ProfessorName
    , StudentsPresent
    , StudentsPresent
    ,  ClassStartTime
    , ClassDate
    , ClassID
FROM UniqueClasses

答案 1 :(得分:1)

这可能对你有用,但我认为只是在你展示的情况下。

BEGIN
        DECLARE @c CURSOR 
        DECLARE @PrevProfName VARCHAR(250) , @PrevClassDateID INT

        DECLARE @NewTable1 TABLE(
            ClassName           VARCHAR(200),
            ProfessorName       VARCHAR(200),
            StudentsPresent     INT,
            ClassStartTime      DATETIME,
            ClassDateClassID    INT)

        DECLARE 
            @ClassName          VARCHAR(200),
            @ProfessorName      VARCHAR(200),
            @StudentsPresent        INT,
            @ClassStartTime     DATETIME,
            @ClassDateClassID   INT

        OPEN @c SELECT * FROM @NewTable1 ORDER BY ClassDateClassID

        FETCH NEXT FROM @c INTO @ClassName, @ProfessorName, @StudentsPresent, @ClassStartTime, @ClassDateClassID

        WHILE @@FETCH_STATUS = 0
            BEGIN
                IF @PrevProfName <> '' AND @PrevClassDateID > 0
                    BEGIN
                        IF @PrevClassDateID = @ClassDateClassID
                            BEGIN
                                SET @PrevProfName = @PrevProfName + ',' + @ProfessorName
                            END
                        ELSE
                            BEGIN
                                INSERT INTO @NewTable1 VALUES(@ClassName, @PrevProfName, @StudentsPresent, @ClassStartTime, @PrevClassDateID)
                                SET @PrevProfName = @ProfessorName
                                SET @PrevClassDateID = @ClassDateClassID
                            END
                    END
                ELSE
                    BEGIN
                        SET @PrevClassDateID = @ClassDateClassID
                        SET @PrevProfName = @ProfessorName
                    END

                FETCH NEXT FROM @c INTO @ClassName, @ProfessorName, @StudentsPresent, @ClassStartTime, @ClassDateClassID
            END
        CLOSE @c
        DEALLOCATE @c

        SELECT * FROM @NewTable1
    END