Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/35.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL将两行或多行转换为一行_Sql_Tsql - Fatal编程技术网

SQL将两行或多行转换为一行

SQL将两行或多行转换为一行,sql,tsql,Sql,Tsql,想象一个学生和多个教授 教授有很多学生 学生们在同一时间和日期上课 表1 ClassName | ProfessorName |StudentsPresent|ClassStartTime |ClassDate |ClassID Philosophy | Stewart |10 |8:00 |01/29/2011 | 1 Philosophy | Kyle |10 |8:00

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

表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 哲学|斯图尔特| 10 | 8:00 | 01/29/2011 | 1 哲学|凯尔| 10 | 8:00 | 01/29/2011 | 1 宗教| Myke | 11 | 8:30 | 01/29/2011 | 2 宗教|南希| 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 ClassName | ProfessorName | StudentsPresent | ClassStartTime | ClassDate | ClassID 哲学|斯图尔特,凯尔| 10 | 8:00 | 01/29/2011 | 1 宗教|梅克,南希| 11 | 8:30 | 01/29/2011 | 2
正如我们所说,我正在研究游标。

这可能适用于您,但我认为您所展示的情况就是如此

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
开始
声明@c游标
声明@PrevProfName VARCHAR(250),@PrevClassDateID INT
声明@NewTable1表(
类名VARCHAR(200),
教授姓名VARCHAR(200),
学生代表,
ClassStartTime日期时间,
ClassDateClassID INT)
声明
@类名VARCHAR(200),
@教授姓名VARCHAR(200),
@学生代表,
@ClassStartTime日期时间,
@ClassDateClassID INT
按ClassDateClassID从@NewTable1订单中打开@c SELECT*
将下一个从@c获取到@ClassName、@ProfessorName、@StudentsPresent、@ClassStartTime、@ClassDateClassID
而@@FETCH\u STATUS=0
开始
如果@PrevProfName“”和@PrevClassDateID>0
开始
如果@PrevClassDateID=@ClassDateClassID
开始
设置@PrevProfName=@PrevProfName+,'+@ProfessorName
结束
其他的
开始
插入@NewTable1值(@ClassName、@PrevProfName、@StudentsPresent、@ClassStartTime、@PrevClassDateID)
设置@PrevProfName=@ProfessorName
设置@PrevClassDateID=@ClassDateClassID
结束
结束
其他的
开始
设置@PrevClassDateID=@ClassDateClassID
设置@PrevProfName=@ProfessorName
结束
将下一个从@c获取到@ClassName、@ProfessorName、@StudentsPresent、@ClassStartTime、@ClassDateClassID
结束
关闭@c
取消分配@c
从@NewTable1中选择*
结束

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

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
开始
声明@c游标
声明@PrevProfName VARCHAR(250),@PrevClassDateID INT
声明@NewTable1表(
类名VARCHAR(200),
教授姓名VARCHAR(200),
学生代表,
ClassStartTime日期时间,
ClassDateClassID INT)
声明
@类名VARCHAR(200),
@教授姓名VARCHAR(200),
@学生代表,
@ClassStartTime日期时间,
@ClassDateClassID INT
按ClassDateClassID从@NewTable1订单中打开@c SELECT*
将下一个从@c获取到@ClassName、@ProfessorName、@StudentsPresent、@ClassStartTime、@ClassDateClassID
而@@FETCH\u STATUS=0
开始
如果@PrevProfName“”和@PrevClassDateID>0
开始
如果@PrevClassDateID=@ClassDateClassID
开始
设置@PrevProfName=@PrevProfName+,'+@ProfessorName
结束
其他的
开始
插入@NewTable1值(@ClassName、@PrevProfName、@StudentsPresent、@ClassStartTime、@PrevClassDateID)
设置@PrevProfName=@ProfessorName
设置@PrevClassDateID=@ClassDateClassID
结束
结束
其他的
开始
设置@PrevClassDateID=@ClassDateClassID
设置@PrevProfName=@ProfessorName
结束
将下一个从@c获取到@ClassName、@ProfessorName、@StudentsPresent、@ClassStartTime、@ClassDateClassID
结束
关闭@c
取消分配@c
从@NewTable1中选择*
结束

您的表似乎非常非规范化。我听说,在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

您的表似乎非常非规范化。我听说,在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

相关:这是家庭作业吗?@Abe:我怀疑。这在T-SQL中是一个很难解决的问题(当然,我想我假设这是针对SQL Server的)。OMG Ponies引用了stackoverflow问题,这是一个重复的问题,它很好地演示了如何获得这种类型的结果。这是一个工作分配。现在我被困在这个问题上了。OMG小马也感谢你的链接,但这并不能解决我的问题,也不能让我知道如何解决这个问题。下面是逻辑:如果ClassName=ClassNameNextRow和ProfessorName=ProfessorNameNextRow和StudentsPresent=StudentsPres