Reputation: 226
I have following Table:
+------+--------------+------------+--------+
| ID | TestID | QuestionId | Answer |
+------+--------------+------------+--------+
| 1 | 10 | 15 | 0 |
| 2 | 10 | 23 | 0 |
| 3 | 10 | 41 | 1 |
| 4 | 16 | 15 | 0 |
| 5 | 16 | 23 | 1 |
| 6 | 16 | 41 | 1 |
| 7 | 24 | 15 | 1 |
| 8 | 24 | 23 | 0 |
| 9 | 24 | 41 | 0 |
+------+--------------+------------+--------+
For internal reports I need following output:
+--------------+----------------+----------------+----------------+
| QuestionId | Test_1 | Test_2 | Test_3 |
+--------------+----------------+----------------+----------------+
| 15 | 0 | 0 | 1 |
| 23 | 0 | 1 | 0 |
| 41 | 1 | 1 | 0 |
+--------------+----------------+----------------+----------------+
I have no idea how to do this. Do you have any suggestions?
Upvotes: 1
Views: 88
Reputation: 95561
One idea:
USE Sandbox;
GO
CREATE TABLE #Test (ID int, TestID int, QuestionID int, Answer tinyint);
INSERT INTO #Test
VALUES (1,10,15,0),
(2,10,23,0),
(3,10,41,1),
(4,16,15,0),
(5,16,23,1),
(6,16,41,1),
(7,24,15,1),
(8,24,23,0),
(9,24,41,0);
GO
WITH Rnks AS (
SELECT *,
DENSE_RANK() OVER (ORDER BY TestID) AS TestNum
FROM #Test T)
SELECT QuestionID,
MAX(CASE WHEN TestNum = 1 THEN Answer END) AS Test_1,
MAX(CASE WHEN TestNum = 2 THEN Answer END) AS Test_2,
MAX(CASE WHEN TestNum = 3 THEN Answer END) AS Test_3
FROM Rnks
GROUP BY QuestionID;
GO
DROP TABLE #Test;
This, however, assumes there are a limited number of tests (and I have guessed the definition of the test_x correctly). If you have an indeterminable amount of tests, you'll need to use dynamic SQL.
Upvotes: 1
Reputation: 93704
Here is one way using conditional aggregation and Row_number
window function
select QuestionId,
Test_1 = max(case when rn = 1 then Answer end),
Test_2 = max(case when rn = 2 then Answer end),
Test_3 = max(case when rn = 3 then Answer end)
from (select *, Rn = row_number()over(partition by QuestionId order by TestID)
from table1) a
group by QuestionId
if the number of tests is unknown then you have to employ dynamic sql
Upvotes: 1
Reputation: 8033
Use Pivot
;WITH CTE
AS
(
SELECT
SeqNo = ROW_NUMBER() OVER(PARTITION BY QuestionId ORDER BY TestId),
*
FROM YourTable
)
SELECT
QuestionId,
Test_1 = MAX([1]),
Test_2 = MAX([2]),
Test_3 = MAX([3])
FROM CTE
PIVOT
(
SUM(Answer)
FOR SeqNo in
(
[1],[2],[3]
)
)P
GROUP BY QuestionId
My Result
Upvotes: 3