如何将多行合并为一行

时间:2023-01-31 09:18:17

All,

Here's my Issue. It's giving a result set but I've got it across multiple rows and I want to put it into one row and get rid of the Nulls in the reading, Writing, Listening, Speaking, and Overall columns.

这是我的问题。它给出了一个结果集,但是我已经把它放到了多行中,我想将它放在一行中,并在阅读,写作,听力,口语和整体列中删除Null。

SQL:

Drop Table #STudentIDs
Declare @SchoolID  NVARCHAR(max) = '2152'
Declare @StudentID NVARCHAR(max) = '1451753'
Declare @TeacherID varchar(max) = '640470'

CREATE TABLE #STudentIDs 
        (
           STudentID INT primary key
        );

      INSERT INTO #StudentIDs
      SELECT Value
      FROM   dbo.Fnsplitid(@StudentID, ',');
      DECLARE @SchoolIDs TABLE
        (
           SchoolID INT
        );

      INSERT INTO @SchoolIDs
      SELECT Value
      FROM   dbo.Fnsplitid(@SchoolID, ',');

         DECLARE @RecentCELDTData TABLE
         (StudentID INT,
         Reading  NVarchar(20),
         Writing NVarchar(20),
         Listening NVarchar(20),
         Speaking NVarchar(20),
         OverallScore NVarchar(20),
         RecentTestDate DATE,
         Overall  BIT)
         INSERT INTO @RecentCELDTData

          SELECT S.StudentID,
          Max(CASE WHEN S.TestComponentCode='L0100' THEN S.TestPerformanceLevelCode ELSE '' END) AS Reading,
          Max(CASE WHEN S.TestComponentCode='L0700' THEN S.TestPerformanceLevelCode ELSE '' END) AS Writing,
          Max(CASE WHEN S.TestComponentCode='L0201' THEN S.TestPerformanceLevelCode ELSE '' END) AS Listening,
          Max(CASE WHEN S.TestComponentCode='L0202' THEN S.TestPerformanceLevelCode ELSE '' END) AS Speaking,
          Max(CASE WHEN S.TestComponentCode='L0800' THEN S.TestPerformanceLevelCode ELSE '' END) AS Overall,
          S.TestDate,
          S.IsSchoolLevelScoreEdit

          FROM (SELECT DISTINCT TD.IsSchoolLevelScoreEdit,STUTCS.StudentID,STUTCS.TestDate,TPLT.TestPerformanceLevelCode,TC.TestComponentCode,
          DENSE_RANK() OVER  (PARTITION BY STUTCS.StudentID ORDER BY stutcs.studentid,STUTCS.TestDate DESC) AS RNK
                       FROM #StudentIDs AS STUS 
               INNER JOIN StudentTestComponentScore(NOLOCK) AS STUTCS
                       ON STUS.StudentID=STUTCS.StudentID 
               INNER JOIN TestPurposeType(NOLOCK) AS TPT
                       ON STUTCS.TestPurposeTypeID=TPT.TestPurposeTypeID
                      -- AND TPT.TestPurposeName='Annual'
               INNER JOIN TestComponentPerformanceMapping(NOLOCK) AS TCPM
                       ON STUTCS.TestComponentPerformanceMappingID=TCPM.TestComponentPerformanceMappingID
               INNER JOIN TestComponent(NOLOCK) AS TC
                       ON TCPM.TestComponentID=TC.TestComponentID
                      AND TC.TestComponentCode IN ('L0100','L0700','L0201','L0202','L0800') 
               INNER JOIN TestScoreType(NOLOCK) AS TST
                       ON TCPM.TestScoreTypeID=TST.TestScoreTypeID
                      AND TST.TestScoreTypeCode='SCAL' 
               INNER JOIN dbo.TestPerformanceLevelType(NOLOCK) TPLT 
                       ON TCPM.TestPerformanceLevelTypeID = TPLT.TestPerformanceLevelTypeID
               INNER JOIN TestDefinition(NOLOCK) AS TD
                       ON TC.TestDefinitionID=TD.TestDefinitionID 
                      AND TD.TestDefinitionCode='CELDT'
                    ) AS S WHERE S.RNK=1  GROUP BY S.StudentID,S.TestDate,S.IsSchoolLevelScoreEdit,S.TestComponentCode,S.TestPerformanceLevelCode
Select * From @RecentCELDTData

Here's the results it gives me:

这是它给我的结果:

StudentID   Reading Writing Listening   Speaking    OverallScore    RecentTestDate  Overall
1451753     3-I                                                     2014-09-05      0
1451753                                 4-EA                        2014-09-05      0
1451753                                             4-EA            2014-09-05      0
1451753                     5-ADV                                   2014-09-05      0
1451753             5-ADV                                           2014-09-05      0

Here's what I need it to look like:

这就是我需要的样子:

StudentID   Reading Writing Listening   Speaking    OverallScore    RecentTestDate  Overall
1451753     3-I     5-ADV   5-ADV       4-EA        4-EA            9/5/2014        0

What do I need to do to Modify the query to accomplish this?

修改查询以完成此操作需要做什么?

Thanks

1 个解决方案

#1


1  

you have S.TestDate and S.IsSchoolLevelScoreEdit in your GROUP BY. So it's probably giving you a record for each test date. Since your output column is called RecentTestDate, you could do a MAX on that column. I'm not sure what IsSchoolLevelScoreEdit means... but if you want to flag it so that if any of them are a one, you could do a max on it as well. The issue being that you can't do a max function on a bit column... so you'd have to convert it. So maybe something like this in your final insert statment?

你的GROUP BY中有S.TestDate和S.IsSchoolLevelScoreEdit。因此,它可能会为您提供每个考试日期的记录。由于您的输出列名为RecentTestDate,因此您可以在该列上执行MAX。我不确定IsSchoolLevelScoreEdit是什么意思......但是如果你想标记它,那么如果它们中的任何一个是一个,你也可以做一个最大值。问题是你不能在位列上执行max函数...所以你必须转换它。在最终的插入语句中可能有这样的东西吗?

    INSERT INTO @RecentCELDTData
    SELECT S.StudentID,
        Max(CASE WHEN S.TestComponentCode='L0100' THEN S.TestPerformanceLevelCode ELSE '' END) AS Reading,
        Max(CASE WHEN S.TestComponentCode='L0700' THEN S.TestPerformanceLevelCode ELSE '' END) AS Writing,
        Max(CASE WHEN S.TestComponentCode='L0201' THEN S.TestPerformanceLevelCode ELSE '' END) AS Listening,
        Max(CASE WHEN S.TestComponentCode='L0202' THEN S.TestPerformanceLevelCode ELSE '' END) AS Speaking,
        Max(CASE WHEN S.TestComponentCode='L0800' THEN S.TestPerformanceLevelCode ELSE '' END) AS Overall,
        max(S.TestDate) as RecentTestDate,
        convert(bit,max(convert(tinyint,S.IsSchoolLevelScoreEdit))) as Overall
    FROM 
        (SELECT DISTINCT TD.IsSchoolLevelScoreEdit,STUTCS.StudentID,STUTCS.TestDate,TPLT.TestPerformanceLevelCode,TC.TestComponentCode, DENSE_RANK() OVER  (PARTITION BY STUTCS.StudentID ORDER BY stutcs.studentid,STUTCS.TestDate DESC) AS RNK
        FROM #StudentIDs AS STUS 
        INNER JOIN StudentTestComponentScore(NOLOCK) AS STUTCS
        ON STUS.StudentID=STUTCS.StudentID 
        INNER JOIN TestPurposeType(NOLOCK) AS TPT
        ON STUTCS.TestPurposeTypeID=TPT.TestPurposeTypeID
        -- AND TPT.TestPurposeName='Annual'
        INNER JOIN TestComponentPerformanceMapping(NOLOCK) AS TCPM
        ON STUTCS.TestComponentPerformanceMappingID=TCPM.TestComponentPerformanceMappingID
        INNER JOIN TestComponent(NOLOCK) AS TC
        ON TCPM.TestComponentID=TC.TestComponentID
        AND TC.TestComponentCode IN ('L0100','L0700','L0201','L0202','L0800') 
        INNER JOIN TestScoreType(NOLOCK) AS TST
        ON TCPM.TestScoreTypeID=TST.TestScoreTypeID
            AND TST.TestScoreTypeCode='SCAL' 
        INNER JOIN dbo.TestPerformanceLevelType(NOLOCK) TPLT 
        ON TCPM.TestPerformanceLevelTypeID = TPLT.TestPerformanceLevelTypeID
        INNER JOIN TestDefinition(NOLOCK) AS TD
        ON TC.TestDefinitionID=TD.TestDefinitionID 
        AND TD.TestDefinitionCode='CELDT'
        ) AS S WHERE S.RNK=1  
    GROUP BY S.StudentID

#1


1  

you have S.TestDate and S.IsSchoolLevelScoreEdit in your GROUP BY. So it's probably giving you a record for each test date. Since your output column is called RecentTestDate, you could do a MAX on that column. I'm not sure what IsSchoolLevelScoreEdit means... but if you want to flag it so that if any of them are a one, you could do a max on it as well. The issue being that you can't do a max function on a bit column... so you'd have to convert it. So maybe something like this in your final insert statment?

你的GROUP BY中有S.TestDate和S.IsSchoolLevelScoreEdit。因此,它可能会为您提供每个考试日期的记录。由于您的输出列名为RecentTestDate,因此您可以在该列上执行MAX。我不确定IsSchoolLevelScoreEdit是什么意思......但是如果你想标记它,那么如果它们中的任何一个是一个,你也可以做一个最大值。问题是你不能在位列上执行max函数...所以你必须转换它。在最终的插入语句中可能有这样的东西吗?

    INSERT INTO @RecentCELDTData
    SELECT S.StudentID,
        Max(CASE WHEN S.TestComponentCode='L0100' THEN S.TestPerformanceLevelCode ELSE '' END) AS Reading,
        Max(CASE WHEN S.TestComponentCode='L0700' THEN S.TestPerformanceLevelCode ELSE '' END) AS Writing,
        Max(CASE WHEN S.TestComponentCode='L0201' THEN S.TestPerformanceLevelCode ELSE '' END) AS Listening,
        Max(CASE WHEN S.TestComponentCode='L0202' THEN S.TestPerformanceLevelCode ELSE '' END) AS Speaking,
        Max(CASE WHEN S.TestComponentCode='L0800' THEN S.TestPerformanceLevelCode ELSE '' END) AS Overall,
        max(S.TestDate) as RecentTestDate,
        convert(bit,max(convert(tinyint,S.IsSchoolLevelScoreEdit))) as Overall
    FROM 
        (SELECT DISTINCT TD.IsSchoolLevelScoreEdit,STUTCS.StudentID,STUTCS.TestDate,TPLT.TestPerformanceLevelCode,TC.TestComponentCode, DENSE_RANK() OVER  (PARTITION BY STUTCS.StudentID ORDER BY stutcs.studentid,STUTCS.TestDate DESC) AS RNK
        FROM #StudentIDs AS STUS 
        INNER JOIN StudentTestComponentScore(NOLOCK) AS STUTCS
        ON STUS.StudentID=STUTCS.StudentID 
        INNER JOIN TestPurposeType(NOLOCK) AS TPT
        ON STUTCS.TestPurposeTypeID=TPT.TestPurposeTypeID
        -- AND TPT.TestPurposeName='Annual'
        INNER JOIN TestComponentPerformanceMapping(NOLOCK) AS TCPM
        ON STUTCS.TestComponentPerformanceMappingID=TCPM.TestComponentPerformanceMappingID
        INNER JOIN TestComponent(NOLOCK) AS TC
        ON TCPM.TestComponentID=TC.TestComponentID
        AND TC.TestComponentCode IN ('L0100','L0700','L0201','L0202','L0800') 
        INNER JOIN TestScoreType(NOLOCK) AS TST
        ON TCPM.TestScoreTypeID=TST.TestScoreTypeID
            AND TST.TestScoreTypeCode='SCAL' 
        INNER JOIN dbo.TestPerformanceLevelType(NOLOCK) TPLT 
        ON TCPM.TestPerformanceLevelTypeID = TPLT.TestPerformanceLevelTypeID
        INNER JOIN TestDefinition(NOLOCK) AS TD
        ON TC.TestDefinitionID=TD.TestDefinitionID 
        AND TD.TestDefinitionCode='CELDT'
        ) AS S WHERE S.RNK=1  
    GROUP BY S.StudentID