Click here to Skip to main content
15,885,899 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I have this data in my database and can display it easily on crystal report
ID	SUB.	GRADE
1	MATHS	D
1	ENGLISH	B-
1	SCIENCE	A
2	MATHS	A
2	ENGLISH	B
2	SCIENCE	B-
3	MATHS	B+
3	ENGLISH	A
3	SCIENCE	A

but I want it in this form
	MATHS	ENGLISH	SCIENCE
1	D	B-	A
2	A	B	B-
3	B+	A	A

pls can anybody help me on how I can achieve this>?
Posted
Updated 18-Apr-13 1:49am
v2

Try this:
SQL
DECLARE @tbl TABLE (ID INT,	[SUB.] NVARCHAR(30), GRADE NVARCHAR(5))

INSERT INTO @tbl (ID, [SUB.], GRADE)
VALUES(1, 'MATHS', 'D')
INSERT INTO @tbl (ID, [SUB.], GRADE)
VALUES(1, 'ENGLISH', 'B-')
INSERT INTO @tbl (ID, [SUB.], GRADE)
VALUES(1, 'SCIENCE', 'A')
INSERT INTO @tbl (ID, [SUB.], GRADE)
VALUES(2, 'MATHS', 'A')
INSERT INTO @tbl (ID, [SUB.], GRADE)
VALUES(2, 'ENGLISH', 'B')
INSERT INTO @tbl (ID, [SUB.], GRADE)
VALUES(2, 'SCIENCE', 'B-')
INSERT INTO @tbl (ID, [SUB.], GRADE)
VALUES(3, 'MATHS', 'B+')
INSERT INTO @tbl (ID, [SUB.], GRADE)
VALUES(3, 'ENGLISH', 'A')
INSERT INTO @tbl (ID, [SUB.], GRADE)
VALUES(3, 'SCIENCE', 'A')

--select from @tbl
SELECT t1.ID, MATHS, ENGLISH, SCIENCE 
FROM (
	SELECT ID, GRADE AS 'MATHS' --select only MATHS data
	FROM @tbl 
	WHERE [SUB.] = 'MATHS'
	) AS t1 INNER JOIN (
			SELECT ID, GRADE AS 'ENGLISH' --join ENGLISH data on ID
			FROM @tbl 
			WHERE [SUB.] = 'ENGLISH'
			) AS t2 ON t1.ID = t2.ID INNER JOIN (
					SELECT ID, GRADE AS 'SCIENCE' --join SCIENCE data on ID
					FROM @tbl 
					WHERE [SUB.] = 'SCIENCE'
				) AS t3 ON t2.ID = t3.ID


Result:
1	D	B-	A
2	A	B	B-
3	B+	A	A


Read about JOIN's[^]
To beeter understan, see this: Visual Representation of SQL Joins[^]

[EDIT #1]
Ok, if you want to fetch data in dynamic way, we need to do some trick. See example:
SQL
IF (OBJECT_ID('#tbl') IS NOT NULL) DROP TABLE #tbl

CREATE TABLE #tbl (ID INT,	[SUB.] NVARCHAR(30), GRADE NVARCHAR(5))

INSERT INTO #tbl (ID, [SUB.], GRADE)
VALUES(1, 'MATHS', 'D')
INSERT INTO #tbl (ID, [SUB.], GRADE)
VALUES(1, 'ENGLISH', 'B-')
INSERT INTO #tbl (ID, [SUB.], GRADE)
VALUES(1, 'SCIENCE', 'A')
INSERT INTO #tbl (ID, [SUB.], GRADE)
VALUES(2, 'MATHS', 'A')
INSERT INTO #tbl (ID, [SUB.], GRADE)
VALUES(2, 'ENGLISH', 'B')
INSERT INTO #tbl (ID, [SUB.], GRADE)
VALUES(2, 'SCIENCE', 'B-')
INSERT INTO #tbl (ID, [SUB.], GRADE)
VALUES(3, 'MATHS', 'B+')
INSERT INTO #tbl (ID, [SUB.], GRADE)
VALUES(3, 'ENGLISH', 'A')
INSERT INTO #tbl (ID, [SUB.], GRADE)
VALUES(3, 'SCIENCE', 'A')

-- for example, i fetch unique grades into second table

IF (OBJECT_ID('#Grades') IS NOT NULL) DROP TABLE #Grades

CREATE TABLE #Grades (IDG INT IDENTITY(1,1), GRADE NVARCHAR(5))

INSERT INTO #Grades (GRADE)
SELECT DISTINCT GRADE
FROM #tbl

--define dynamic columns for SUB.
DECLARE @cols NVARCHAR(200)
SET @cols = STUFF((SELECT DISTINCT '],[' + [SUB.]
					FROM #tbl
					ORDER BY '],[' + [SUB.]
			FOR XML PATH('')),1,2,'') + ']'

--define data table
DECLARE @dt NVARCHAR(2000)

SET @dt = 'SELECT t1.ID, t1.[SUB.], t2.IDG ' + 
		'FROM #tbl AS t1 INNER JOIN #Grades AS t2 ON t1.GRADE = t2.GRADE'
--EXEC(@dt)

--define pivot table
DECLARE @pt NVARCHAR(MAX)

SET @pt = 'SELECT ID, ' + @cols + ' ' +
'FROM (' + @dt + ') AS DT ' + 
'PIVOT(MAX(IDG) FOR [SUB.] IN(' + @cols + ')) AS PT '

EXEC(@pt)

--clean up ;)
DROP TABLE #Grades
DROP TABLE #tbl


Result:
ID   ENGLISH  MATHS   SCIENCE
1	3	5	1
2	2	1	3
3	1	4	1


Change the code to your needs ;)
[EDIT]
 
Share this answer
 
v3
Comments
wizy@2020 18-Apr-13 8:24am    
pls I understand your solution but the subjects are dynamic, they can change anytime
Maciej Los 18-Apr-13 8:35am    
OK, i'll add a comments. Please, see another solution (in my opinion is more readible).
Maciej Los 18-Apr-13 14:21pm    
Dynamic columns added ;)
Member 14108724 20-Apr-19 6:13am    
The data in the table is already in the database then why you have created the table manually with the values? My point is the data should be directly fitched from the database.
Maciej Los 22-Apr-19 14:57pm    
What?
Another solution is to use temporary table:
SQL
--how to create @tbl? 
--see solution1
DECLARE @dst TABLE (ID INT , MATHS NVARCHAR(5) NULL, ENGLISH NVARCHAR(5) NULL, SCIENCE NVARCHAR(5) NULL)

--add maths
INSERT INTO @dst (ID, MATHS)
SELECT ID, GRADE AS 'MATHS'
FROM @tbl
WHERE [SUB.] = 'MATHS'

--uncomment this to check values
--SELECT *
--FROM @dst

--update on ID to add ENGLISH
UPDATE @dst SET t1.ENGLISH = t2.ENGLISH
FROM @dst AS t1 INNER JOIN (
	SELECT ID, GRADE AS 'ENGLISH'
	FROM @tbl 
	WHERE [SUB.] = 'ENGLISH'
	) AS t2 ON t1.ID = t2.ID

--uncomment this to check values
--SELECT *
--FROM @dst

--update on ID to add SCIENCE
UPDATE @dst SET t1.SCIENCE = t2.SCIENCE
FROM @dst AS t1 INNER JOIN (
	SELECT ID, GRADE AS 'SCIENCE'
	FROM @tbl 
	WHERE [SUB.] = 'SCIENCE'
	) AS t2 ON t1.ID = t2.ID

SELECT *
FROM @dst
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900