Skip to content
Advertisement

Select rows after the current row which are null and combine them to rows

I have written the following SQL code to display the data as rows, where the row after data is having null values except on the description column.

DECLARE @StudentData TABLE
(
  RowID INT NOT NULL PRIMARY KEY IDENTITY(1,1),
  RemarksDate NVARCHAR(20),
  StudentName NVARCHAR(1000),
 Description NVARCHAR(MAX),
  TotStudents NVARCHAR(100)
)

INSERT INTO @StudentData(RemarksDate, StudentName, Description, TotStudents)
VALUES('2/1/2021', NULL, 'Poor In English', '14'),
(NULL, NULL, '1 ABC', NULL),
(NULL, NULL, '1 XYZ', NULL),
(NULL, NULL, '1 MNO', NULL),
(NULL, NULL, '1 IGH', NULL),
(NULL, NULL, '10 KKK', NULL),
('2/1/2021', NULL, 'Poor In Maths', '5'),
(NULL, NULL, '5 PQR', NULL),
('2/8/2021', NULL, 'Poor In Social', '1'),
(NULL, NULL, '1 RST', NULL)

This results in the output as follows:

enter image description here

I have written the following query to group and display rows:

SELECT t1.RemarksDate, LTRIM(RIGHT(t2.Description, LEN(t2.Description) - PATINDEX('%[0-9][^0- 9]%', t2.Description ))) StudentName, t1.Description
 ,LEFT(t2.Description, PATINDEX('%[0-9][^0-9]%', t2.Description ))
 FROM (
 SELECT *, RowID + TotStudents MaxVal
 FROM @StudentData
 WHERE RemarksDate is NOT NULL
 ) t1 
  JOIN (
   SELECT * 
   FROM @StudentData
   WHERE RemarksDate is NULL
  ) t2 ON t2.RowId BETWEEN t1.RowID and t1.MaxVal 

The data is displayed as follows

enter image description here

Expected output is as follows

2/1/2021    ABC Poor In English 1
2/1/2021    XYZ Poor In English 1
2/1/2021    MNO Poor In English 1
2/1/2021    IGH Poor In English 1
2/1/2021    KKK Poor In English 10
2/1/2021    PQR Poor In Maths   5
2/8/2021    RST Poor In Social  1

Advertisement

Answer

Except the fact that the table design is pretty awful, I would suggest the following approach:

WITH cteRemarks AS(
  SELECT *, LEAD(RowId) OVER (ORDER BY RowID) AS RowIdNxt
    FROM @StudentData
    WHERE TotStudents IS NOT NULL
)
SELECT r.RemarksDate
      ,RIGHT(t.Description, LEN(t.Description)-CHARINDEX(' ', t.Description)) AS StudentsName
      ,r.Description AS Description
      ,LEFT(t.Description, CHARINDEX(' ', t.Description)-1) AS Val
  FROM cteRemarks r
  LEFT JOIN @StudentData t ON t.TotStudents IS NULL
                           AND t.RowID > r.RowID
                           AND t.RowID < ISNULL(r.RowIDNxt, 99999999)
User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement