MSSQL get top 4 values from 12 columns
I need some assistance here. I have a result set as per below:
Name | IdNumber | Subject1 |Percentage | Subject2 | Percentage | Subject3 | Percentage | (...until subject 12)
I need to return only the 4 subjects and their percentage that the student scored the highest in.
Getting the highest mark per student is easy, I've done it this way:
SELECT [Other Fields],
(SELECT Max(v)
FROM (VALUES (date1), (date2), (date3),...) AS value(v)) as [MaxDate]
FROM [YourTableName]
Getting the other 4 is the problem.
sql
|
show 6 more comments
I need some assistance here. I have a result set as per below:
Name | IdNumber | Subject1 |Percentage | Subject2 | Percentage | Subject3 | Percentage | (...until subject 12)
I need to return only the 4 subjects and their percentage that the student scored the highest in.
Getting the highest mark per student is easy, I've done it this way:
SELECT [Other Fields],
(SELECT Max(v)
FROM (VALUES (date1), (date2), (date3),...) AS value(v)) as [MaxDate]
FROM [YourTableName]
Getting the other 4 is the problem.
sql
2
Add some sample table data and the expected result - all as formatted text, not images. Consider simplifying the problem, perhaps just 3 subjects will do fine?
– jarlh
Nov 16 '18 at 9:14
2
Why not fix your table structure first? Having repeated groups of columns is a broken design.
– Damien_The_Unbeliever
Nov 16 '18 at 9:30
3
Normalising the schema design would make this sort of query a lot easier. If the person who demands a flat table design is stuck in their ways, perhaps create a view to satisfy them while keeping a sensible design under the hood?
– Diado
Nov 16 '18 at 9:38
3
How they want to have the data presented to them should not dictate how the data is stored.
– Damien_The_Unbeliever
Nov 16 '18 at 9:38
1
If you created that table, change it: Create the table normalized and add a view PIVOting it for the person who requested that result
– dnoeth
Nov 16 '18 at 9:50
|
show 6 more comments
I need some assistance here. I have a result set as per below:
Name | IdNumber | Subject1 |Percentage | Subject2 | Percentage | Subject3 | Percentage | (...until subject 12)
I need to return only the 4 subjects and their percentage that the student scored the highest in.
Getting the highest mark per student is easy, I've done it this way:
SELECT [Other Fields],
(SELECT Max(v)
FROM (VALUES (date1), (date2), (date3),...) AS value(v)) as [MaxDate]
FROM [YourTableName]
Getting the other 4 is the problem.
sql
I need some assistance here. I have a result set as per below:
Name | IdNumber | Subject1 |Percentage | Subject2 | Percentage | Subject3 | Percentage | (...until subject 12)
I need to return only the 4 subjects and their percentage that the student scored the highest in.
Getting the highest mark per student is easy, I've done it this way:
SELECT [Other Fields],
(SELECT Max(v)
FROM (VALUES (date1), (date2), (date3),...) AS value(v)) as [MaxDate]
FROM [YourTableName]
Getting the other 4 is the problem.
sql
sql
edited Nov 16 '18 at 15:20
Andy Hames
32419
32419
asked Nov 16 '18 at 9:12
KalynKalyn
404
404
2
Add some sample table data and the expected result - all as formatted text, not images. Consider simplifying the problem, perhaps just 3 subjects will do fine?
– jarlh
Nov 16 '18 at 9:14
2
Why not fix your table structure first? Having repeated groups of columns is a broken design.
– Damien_The_Unbeliever
Nov 16 '18 at 9:30
3
Normalising the schema design would make this sort of query a lot easier. If the person who demands a flat table design is stuck in their ways, perhaps create a view to satisfy them while keeping a sensible design under the hood?
– Diado
Nov 16 '18 at 9:38
3
How they want to have the data presented to them should not dictate how the data is stored.
– Damien_The_Unbeliever
Nov 16 '18 at 9:38
1
If you created that table, change it: Create the table normalized and add a view PIVOting it for the person who requested that result
– dnoeth
Nov 16 '18 at 9:50
|
show 6 more comments
2
Add some sample table data and the expected result - all as formatted text, not images. Consider simplifying the problem, perhaps just 3 subjects will do fine?
– jarlh
Nov 16 '18 at 9:14
2
Why not fix your table structure first? Having repeated groups of columns is a broken design.
– Damien_The_Unbeliever
Nov 16 '18 at 9:30
3
Normalising the schema design would make this sort of query a lot easier. If the person who demands a flat table design is stuck in their ways, perhaps create a view to satisfy them while keeping a sensible design under the hood?
– Diado
Nov 16 '18 at 9:38
3
How they want to have the data presented to them should not dictate how the data is stored.
– Damien_The_Unbeliever
Nov 16 '18 at 9:38
1
If you created that table, change it: Create the table normalized and add a view PIVOting it for the person who requested that result
– dnoeth
Nov 16 '18 at 9:50
2
2
Add some sample table data and the expected result - all as formatted text, not images. Consider simplifying the problem, perhaps just 3 subjects will do fine?
– jarlh
Nov 16 '18 at 9:14
Add some sample table data and the expected result - all as formatted text, not images. Consider simplifying the problem, perhaps just 3 subjects will do fine?
– jarlh
Nov 16 '18 at 9:14
2
2
Why not fix your table structure first? Having repeated groups of columns is a broken design.
– Damien_The_Unbeliever
Nov 16 '18 at 9:30
Why not fix your table structure first? Having repeated groups of columns is a broken design.
– Damien_The_Unbeliever
Nov 16 '18 at 9:30
3
3
Normalising the schema design would make this sort of query a lot easier. If the person who demands a flat table design is stuck in their ways, perhaps create a view to satisfy them while keeping a sensible design under the hood?
– Diado
Nov 16 '18 at 9:38
Normalising the schema design would make this sort of query a lot easier. If the person who demands a flat table design is stuck in their ways, perhaps create a view to satisfy them while keeping a sensible design under the hood?
– Diado
Nov 16 '18 at 9:38
3
3
How they want to have the data presented to them should not dictate how the data is stored.
– Damien_The_Unbeliever
Nov 16 '18 at 9:38
How they want to have the data presented to them should not dictate how the data is stored.
– Damien_The_Unbeliever
Nov 16 '18 at 9:38
1
1
If you created that table, change it: Create the table normalized and add a view PIVOting it for the person who requested that result
– dnoeth
Nov 16 '18 at 9:50
If you created that table, change it: Create the table normalized and add a view PIVOting it for the person who requested that result
– dnoeth
Nov 16 '18 at 9:50
|
show 6 more comments
4 Answers
4
active
oldest
votes
Try to unpivot data as the data you have is not normalised and then pivot data again.
Preparing data:
DECLARE @FooTable TABLE
( Name VARCHAR(10), IdNumber INT,
Subject1 VARCHAR(100), Percentage1 INT,
Subject2 VARCHAR(10), Percentage2 INT,
Subject3 VARCHAR(10), Percentage3 INT,
Subject4 VARCHAR(10), Percentage4 INT
)
INSERT INTO @FooTable
(
Name, IdNumber,
Subject1, Percentage1,
Subject2, Percentage2,
Subject3, Percentage3,
Subject4, Percentage4
)
VALUES
( 'Name 1', -- Name - varchar(10)
1,
'Subject 1', -- Subject1 - varchar(10)
10, -- Percentage1 - int
'Subject 2', -- Subject2 - varchar(10)
20, -- Percentage2 - int
'Subject 3', -- Subject3 - varchar(10)
30, -- Percentage3 - int
'Subject 4', -- Subject4 - varchar(10)
40 -- Percentage4 - int
)
, ('Name 2', -- Name - varchar(10)
2,
'Subject 1', -- Subject1 - varchar(10)
20, -- Percentage1 - int
'Subject 2', -- Subject2 - varchar(10)
30, -- Percentage2 - int
'Subject 3', -- Subject3 - varchar(10)
40, -- Percentage3 - int
'Subject 4', -- Subject4 - varchar(10)
50 -- Percentage4 - int)
)
, ('Name 3', -- Name - varchar(10)
3,
'Subject 1', -- Subject1 - varchar(10)
30, -- Percentage1 - int
'Subject 2', -- Subject2 - varchar(10)
40, -- Percentage2 - int
'Subject 3', -- Subject3 - varchar(10)
50, -- Percentage3 - int
'Subject 4', -- Subject4 - varchar(10)
60 -- Percentage4 - int)
)
SELECT * FROM @FooTable
Unpivoting data and pivoting data:
;WITH cte
AS (SELECT *,
ROW_NUMBER() OVER (PARTITION BY Name ORDER BY percentage DESC) AS rn
FROM
(
SELECT Name,
Percentage1,
Percentage2,
Percentage3,
Percentage4
FROM @FooTable
) p
UNPIVOT
(
percentage
FOR subject IN (Percentage1, Percentage2, Percentage3, Percentage4)
) up)
SELECT *
FROM (
SELECT cte.percentage, cte.subject
FROM cte
WHERE rn IN ( 1, 2, 3, 4 )
)source
PIVOT
(
MAX(percentage)
FOR subject IN ([Percentage1],[Percentage2],[Percentage3],[Percentage4])
)q
Output:

Here while pivoting the data in the result set we need to consider all the 12 combinations because the top 4 subjects will be different for each student
– Sanal Sunny
Nov 16 '18 at 13:04
@SanalSunny OP can add these columns into the table.
– StepUp
Nov 16 '18 at 13:14
add a comment |
If you don't wish to change your table structure then you need to UNPIVOT the data after that you can select the top 4 subjects
;WITH cte AS (
SELECT *,ROW_NUMBER() OVER (PARTITION BY Name ORDER BY Percentage DESC) AS rn
FROM
(SELECT Name,percentage1,percentage2,percentage3,percentage4
,percentage5,percentage6,percentage7,percentage8
,percentage9,percentage10,percentage11,percentage12
FROM r ) p
UNPIVOT
(percentage FOR subject IN (,percentage1,percentage2,percentage3,percentage4
,percentage5,percentage6,percentage7,percentage8
,percentage9,percentage10,percentage11,percentage12)
) up )
SELECT * FROM cte
WHERE rn IN (1,2,3,4)
Thank you for making me aware of the PIVOT and UNPIVOT operators. :-)
– johey
Nov 16 '18 at 9:58
add a comment |
The data structure is build in a way that makes things much more complicated as they could be.
You are not allowed to change that. Ok.
We need to do something ugly to deal with that ugly data structure.
Define a view that normalizes the structure. Then you can work in a normal way querying that view.
The view would look like:
select Name, IdNumber, Subject1 as Subject, Percentage1 as Percentage, 1 as SubjectNumber
union all
select Name, IdNumber, Subject2 as Subject, Percentage2 as Percentage, 2 as SubjectNumber
...
That should be much easier to deal with.
If this was for production somehow, you should try to set things straight much earlier.
1
Better switch to UNION ALL
– dnoeth
Nov 16 '18 at 9:51
@dnoeth You're right
– jhinghaus
Nov 16 '18 at 9:53
Thank you Guys for all the assistance. one of the posts helped. but i cant find it now, i think they removed their post
– Kalyn
Nov 16 '18 at 12:09
add a comment |
Thank you Guys for all the assistance. one of the posts helped. but i cant find it now, i think they removed their post
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53334654%2fmssql-get-top-4-values-from-12-columns%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
Try to unpivot data as the data you have is not normalised and then pivot data again.
Preparing data:
DECLARE @FooTable TABLE
( Name VARCHAR(10), IdNumber INT,
Subject1 VARCHAR(100), Percentage1 INT,
Subject2 VARCHAR(10), Percentage2 INT,
Subject3 VARCHAR(10), Percentage3 INT,
Subject4 VARCHAR(10), Percentage4 INT
)
INSERT INTO @FooTable
(
Name, IdNumber,
Subject1, Percentage1,
Subject2, Percentage2,
Subject3, Percentage3,
Subject4, Percentage4
)
VALUES
( 'Name 1', -- Name - varchar(10)
1,
'Subject 1', -- Subject1 - varchar(10)
10, -- Percentage1 - int
'Subject 2', -- Subject2 - varchar(10)
20, -- Percentage2 - int
'Subject 3', -- Subject3 - varchar(10)
30, -- Percentage3 - int
'Subject 4', -- Subject4 - varchar(10)
40 -- Percentage4 - int
)
, ('Name 2', -- Name - varchar(10)
2,
'Subject 1', -- Subject1 - varchar(10)
20, -- Percentage1 - int
'Subject 2', -- Subject2 - varchar(10)
30, -- Percentage2 - int
'Subject 3', -- Subject3 - varchar(10)
40, -- Percentage3 - int
'Subject 4', -- Subject4 - varchar(10)
50 -- Percentage4 - int)
)
, ('Name 3', -- Name - varchar(10)
3,
'Subject 1', -- Subject1 - varchar(10)
30, -- Percentage1 - int
'Subject 2', -- Subject2 - varchar(10)
40, -- Percentage2 - int
'Subject 3', -- Subject3 - varchar(10)
50, -- Percentage3 - int
'Subject 4', -- Subject4 - varchar(10)
60 -- Percentage4 - int)
)
SELECT * FROM @FooTable
Unpivoting data and pivoting data:
;WITH cte
AS (SELECT *,
ROW_NUMBER() OVER (PARTITION BY Name ORDER BY percentage DESC) AS rn
FROM
(
SELECT Name,
Percentage1,
Percentage2,
Percentage3,
Percentage4
FROM @FooTable
) p
UNPIVOT
(
percentage
FOR subject IN (Percentage1, Percentage2, Percentage3, Percentage4)
) up)
SELECT *
FROM (
SELECT cte.percentage, cte.subject
FROM cte
WHERE rn IN ( 1, 2, 3, 4 )
)source
PIVOT
(
MAX(percentage)
FOR subject IN ([Percentage1],[Percentage2],[Percentage3],[Percentage4])
)q
Output:

Here while pivoting the data in the result set we need to consider all the 12 combinations because the top 4 subjects will be different for each student
– Sanal Sunny
Nov 16 '18 at 13:04
@SanalSunny OP can add these columns into the table.
– StepUp
Nov 16 '18 at 13:14
add a comment |
Try to unpivot data as the data you have is not normalised and then pivot data again.
Preparing data:
DECLARE @FooTable TABLE
( Name VARCHAR(10), IdNumber INT,
Subject1 VARCHAR(100), Percentage1 INT,
Subject2 VARCHAR(10), Percentage2 INT,
Subject3 VARCHAR(10), Percentage3 INT,
Subject4 VARCHAR(10), Percentage4 INT
)
INSERT INTO @FooTable
(
Name, IdNumber,
Subject1, Percentage1,
Subject2, Percentage2,
Subject3, Percentage3,
Subject4, Percentage4
)
VALUES
( 'Name 1', -- Name - varchar(10)
1,
'Subject 1', -- Subject1 - varchar(10)
10, -- Percentage1 - int
'Subject 2', -- Subject2 - varchar(10)
20, -- Percentage2 - int
'Subject 3', -- Subject3 - varchar(10)
30, -- Percentage3 - int
'Subject 4', -- Subject4 - varchar(10)
40 -- Percentage4 - int
)
, ('Name 2', -- Name - varchar(10)
2,
'Subject 1', -- Subject1 - varchar(10)
20, -- Percentage1 - int
'Subject 2', -- Subject2 - varchar(10)
30, -- Percentage2 - int
'Subject 3', -- Subject3 - varchar(10)
40, -- Percentage3 - int
'Subject 4', -- Subject4 - varchar(10)
50 -- Percentage4 - int)
)
, ('Name 3', -- Name - varchar(10)
3,
'Subject 1', -- Subject1 - varchar(10)
30, -- Percentage1 - int
'Subject 2', -- Subject2 - varchar(10)
40, -- Percentage2 - int
'Subject 3', -- Subject3 - varchar(10)
50, -- Percentage3 - int
'Subject 4', -- Subject4 - varchar(10)
60 -- Percentage4 - int)
)
SELECT * FROM @FooTable
Unpivoting data and pivoting data:
;WITH cte
AS (SELECT *,
ROW_NUMBER() OVER (PARTITION BY Name ORDER BY percentage DESC) AS rn
FROM
(
SELECT Name,
Percentage1,
Percentage2,
Percentage3,
Percentage4
FROM @FooTable
) p
UNPIVOT
(
percentage
FOR subject IN (Percentage1, Percentage2, Percentage3, Percentage4)
) up)
SELECT *
FROM (
SELECT cte.percentage, cte.subject
FROM cte
WHERE rn IN ( 1, 2, 3, 4 )
)source
PIVOT
(
MAX(percentage)
FOR subject IN ([Percentage1],[Percentage2],[Percentage3],[Percentage4])
)q
Output:

Here while pivoting the data in the result set we need to consider all the 12 combinations because the top 4 subjects will be different for each student
– Sanal Sunny
Nov 16 '18 at 13:04
@SanalSunny OP can add these columns into the table.
– StepUp
Nov 16 '18 at 13:14
add a comment |
Try to unpivot data as the data you have is not normalised and then pivot data again.
Preparing data:
DECLARE @FooTable TABLE
( Name VARCHAR(10), IdNumber INT,
Subject1 VARCHAR(100), Percentage1 INT,
Subject2 VARCHAR(10), Percentage2 INT,
Subject3 VARCHAR(10), Percentage3 INT,
Subject4 VARCHAR(10), Percentage4 INT
)
INSERT INTO @FooTable
(
Name, IdNumber,
Subject1, Percentage1,
Subject2, Percentage2,
Subject3, Percentage3,
Subject4, Percentage4
)
VALUES
( 'Name 1', -- Name - varchar(10)
1,
'Subject 1', -- Subject1 - varchar(10)
10, -- Percentage1 - int
'Subject 2', -- Subject2 - varchar(10)
20, -- Percentage2 - int
'Subject 3', -- Subject3 - varchar(10)
30, -- Percentage3 - int
'Subject 4', -- Subject4 - varchar(10)
40 -- Percentage4 - int
)
, ('Name 2', -- Name - varchar(10)
2,
'Subject 1', -- Subject1 - varchar(10)
20, -- Percentage1 - int
'Subject 2', -- Subject2 - varchar(10)
30, -- Percentage2 - int
'Subject 3', -- Subject3 - varchar(10)
40, -- Percentage3 - int
'Subject 4', -- Subject4 - varchar(10)
50 -- Percentage4 - int)
)
, ('Name 3', -- Name - varchar(10)
3,
'Subject 1', -- Subject1 - varchar(10)
30, -- Percentage1 - int
'Subject 2', -- Subject2 - varchar(10)
40, -- Percentage2 - int
'Subject 3', -- Subject3 - varchar(10)
50, -- Percentage3 - int
'Subject 4', -- Subject4 - varchar(10)
60 -- Percentage4 - int)
)
SELECT * FROM @FooTable
Unpivoting data and pivoting data:
;WITH cte
AS (SELECT *,
ROW_NUMBER() OVER (PARTITION BY Name ORDER BY percentage DESC) AS rn
FROM
(
SELECT Name,
Percentage1,
Percentage2,
Percentage3,
Percentage4
FROM @FooTable
) p
UNPIVOT
(
percentage
FOR subject IN (Percentage1, Percentage2, Percentage3, Percentage4)
) up)
SELECT *
FROM (
SELECT cte.percentage, cte.subject
FROM cte
WHERE rn IN ( 1, 2, 3, 4 )
)source
PIVOT
(
MAX(percentage)
FOR subject IN ([Percentage1],[Percentage2],[Percentage3],[Percentage4])
)q
Output:

Try to unpivot data as the data you have is not normalised and then pivot data again.
Preparing data:
DECLARE @FooTable TABLE
( Name VARCHAR(10), IdNumber INT,
Subject1 VARCHAR(100), Percentage1 INT,
Subject2 VARCHAR(10), Percentage2 INT,
Subject3 VARCHAR(10), Percentage3 INT,
Subject4 VARCHAR(10), Percentage4 INT
)
INSERT INTO @FooTable
(
Name, IdNumber,
Subject1, Percentage1,
Subject2, Percentage2,
Subject3, Percentage3,
Subject4, Percentage4
)
VALUES
( 'Name 1', -- Name - varchar(10)
1,
'Subject 1', -- Subject1 - varchar(10)
10, -- Percentage1 - int
'Subject 2', -- Subject2 - varchar(10)
20, -- Percentage2 - int
'Subject 3', -- Subject3 - varchar(10)
30, -- Percentage3 - int
'Subject 4', -- Subject4 - varchar(10)
40 -- Percentage4 - int
)
, ('Name 2', -- Name - varchar(10)
2,
'Subject 1', -- Subject1 - varchar(10)
20, -- Percentage1 - int
'Subject 2', -- Subject2 - varchar(10)
30, -- Percentage2 - int
'Subject 3', -- Subject3 - varchar(10)
40, -- Percentage3 - int
'Subject 4', -- Subject4 - varchar(10)
50 -- Percentage4 - int)
)
, ('Name 3', -- Name - varchar(10)
3,
'Subject 1', -- Subject1 - varchar(10)
30, -- Percentage1 - int
'Subject 2', -- Subject2 - varchar(10)
40, -- Percentage2 - int
'Subject 3', -- Subject3 - varchar(10)
50, -- Percentage3 - int
'Subject 4', -- Subject4 - varchar(10)
60 -- Percentage4 - int)
)
SELECT * FROM @FooTable
Unpivoting data and pivoting data:
;WITH cte
AS (SELECT *,
ROW_NUMBER() OVER (PARTITION BY Name ORDER BY percentage DESC) AS rn
FROM
(
SELECT Name,
Percentage1,
Percentage2,
Percentage3,
Percentage4
FROM @FooTable
) p
UNPIVOT
(
percentage
FOR subject IN (Percentage1, Percentage2, Percentage3, Percentage4)
) up)
SELECT *
FROM (
SELECT cte.percentage, cte.subject
FROM cte
WHERE rn IN ( 1, 2, 3, 4 )
)source
PIVOT
(
MAX(percentage)
FOR subject IN ([Percentage1],[Percentage2],[Percentage3],[Percentage4])
)q
Output:

answered Nov 16 '18 at 10:19
StepUpStepUp
7,40474473
7,40474473
Here while pivoting the data in the result set we need to consider all the 12 combinations because the top 4 subjects will be different for each student
– Sanal Sunny
Nov 16 '18 at 13:04
@SanalSunny OP can add these columns into the table.
– StepUp
Nov 16 '18 at 13:14
add a comment |
Here while pivoting the data in the result set we need to consider all the 12 combinations because the top 4 subjects will be different for each student
– Sanal Sunny
Nov 16 '18 at 13:04
@SanalSunny OP can add these columns into the table.
– StepUp
Nov 16 '18 at 13:14
Here while pivoting the data in the result set we need to consider all the 12 combinations because the top 4 subjects will be different for each student
– Sanal Sunny
Nov 16 '18 at 13:04
Here while pivoting the data in the result set we need to consider all the 12 combinations because the top 4 subjects will be different for each student
– Sanal Sunny
Nov 16 '18 at 13:04
@SanalSunny OP can add these columns into the table.
– StepUp
Nov 16 '18 at 13:14
@SanalSunny OP can add these columns into the table.
– StepUp
Nov 16 '18 at 13:14
add a comment |
If you don't wish to change your table structure then you need to UNPIVOT the data after that you can select the top 4 subjects
;WITH cte AS (
SELECT *,ROW_NUMBER() OVER (PARTITION BY Name ORDER BY Percentage DESC) AS rn
FROM
(SELECT Name,percentage1,percentage2,percentage3,percentage4
,percentage5,percentage6,percentage7,percentage8
,percentage9,percentage10,percentage11,percentage12
FROM r ) p
UNPIVOT
(percentage FOR subject IN (,percentage1,percentage2,percentage3,percentage4
,percentage5,percentage6,percentage7,percentage8
,percentage9,percentage10,percentage11,percentage12)
) up )
SELECT * FROM cte
WHERE rn IN (1,2,3,4)
Thank you for making me aware of the PIVOT and UNPIVOT operators. :-)
– johey
Nov 16 '18 at 9:58
add a comment |
If you don't wish to change your table structure then you need to UNPIVOT the data after that you can select the top 4 subjects
;WITH cte AS (
SELECT *,ROW_NUMBER() OVER (PARTITION BY Name ORDER BY Percentage DESC) AS rn
FROM
(SELECT Name,percentage1,percentage2,percentage3,percentage4
,percentage5,percentage6,percentage7,percentage8
,percentage9,percentage10,percentage11,percentage12
FROM r ) p
UNPIVOT
(percentage FOR subject IN (,percentage1,percentage2,percentage3,percentage4
,percentage5,percentage6,percentage7,percentage8
,percentage9,percentage10,percentage11,percentage12)
) up )
SELECT * FROM cte
WHERE rn IN (1,2,3,4)
Thank you for making me aware of the PIVOT and UNPIVOT operators. :-)
– johey
Nov 16 '18 at 9:58
add a comment |
If you don't wish to change your table structure then you need to UNPIVOT the data after that you can select the top 4 subjects
;WITH cte AS (
SELECT *,ROW_NUMBER() OVER (PARTITION BY Name ORDER BY Percentage DESC) AS rn
FROM
(SELECT Name,percentage1,percentage2,percentage3,percentage4
,percentage5,percentage6,percentage7,percentage8
,percentage9,percentage10,percentage11,percentage12
FROM r ) p
UNPIVOT
(percentage FOR subject IN (,percentage1,percentage2,percentage3,percentage4
,percentage5,percentage6,percentage7,percentage8
,percentage9,percentage10,percentage11,percentage12)
) up )
SELECT * FROM cte
WHERE rn IN (1,2,3,4)
If you don't wish to change your table structure then you need to UNPIVOT the data after that you can select the top 4 subjects
;WITH cte AS (
SELECT *,ROW_NUMBER() OVER (PARTITION BY Name ORDER BY Percentage DESC) AS rn
FROM
(SELECT Name,percentage1,percentage2,percentage3,percentage4
,percentage5,percentage6,percentage7,percentage8
,percentage9,percentage10,percentage11,percentage12
FROM r ) p
UNPIVOT
(percentage FOR subject IN (,percentage1,percentage2,percentage3,percentage4
,percentage5,percentage6,percentage7,percentage8
,percentage9,percentage10,percentage11,percentage12)
) up )
SELECT * FROM cte
WHERE rn IN (1,2,3,4)
answered Nov 16 '18 at 9:51
Sanal SunnySanal Sunny
6628
6628
Thank you for making me aware of the PIVOT and UNPIVOT operators. :-)
– johey
Nov 16 '18 at 9:58
add a comment |
Thank you for making me aware of the PIVOT and UNPIVOT operators. :-)
– johey
Nov 16 '18 at 9:58
Thank you for making me aware of the PIVOT and UNPIVOT operators. :-)
– johey
Nov 16 '18 at 9:58
Thank you for making me aware of the PIVOT and UNPIVOT operators. :-)
– johey
Nov 16 '18 at 9:58
add a comment |
The data structure is build in a way that makes things much more complicated as they could be.
You are not allowed to change that. Ok.
We need to do something ugly to deal with that ugly data structure.
Define a view that normalizes the structure. Then you can work in a normal way querying that view.
The view would look like:
select Name, IdNumber, Subject1 as Subject, Percentage1 as Percentage, 1 as SubjectNumber
union all
select Name, IdNumber, Subject2 as Subject, Percentage2 as Percentage, 2 as SubjectNumber
...
That should be much easier to deal with.
If this was for production somehow, you should try to set things straight much earlier.
1
Better switch to UNION ALL
– dnoeth
Nov 16 '18 at 9:51
@dnoeth You're right
– jhinghaus
Nov 16 '18 at 9:53
Thank you Guys for all the assistance. one of the posts helped. but i cant find it now, i think they removed their post
– Kalyn
Nov 16 '18 at 12:09
add a comment |
The data structure is build in a way that makes things much more complicated as they could be.
You are not allowed to change that. Ok.
We need to do something ugly to deal with that ugly data structure.
Define a view that normalizes the structure. Then you can work in a normal way querying that view.
The view would look like:
select Name, IdNumber, Subject1 as Subject, Percentage1 as Percentage, 1 as SubjectNumber
union all
select Name, IdNumber, Subject2 as Subject, Percentage2 as Percentage, 2 as SubjectNumber
...
That should be much easier to deal with.
If this was for production somehow, you should try to set things straight much earlier.
1
Better switch to UNION ALL
– dnoeth
Nov 16 '18 at 9:51
@dnoeth You're right
– jhinghaus
Nov 16 '18 at 9:53
Thank you Guys for all the assistance. one of the posts helped. but i cant find it now, i think they removed their post
– Kalyn
Nov 16 '18 at 12:09
add a comment |
The data structure is build in a way that makes things much more complicated as they could be.
You are not allowed to change that. Ok.
We need to do something ugly to deal with that ugly data structure.
Define a view that normalizes the structure. Then you can work in a normal way querying that view.
The view would look like:
select Name, IdNumber, Subject1 as Subject, Percentage1 as Percentage, 1 as SubjectNumber
union all
select Name, IdNumber, Subject2 as Subject, Percentage2 as Percentage, 2 as SubjectNumber
...
That should be much easier to deal with.
If this was for production somehow, you should try to set things straight much earlier.
The data structure is build in a way that makes things much more complicated as they could be.
You are not allowed to change that. Ok.
We need to do something ugly to deal with that ugly data structure.
Define a view that normalizes the structure. Then you can work in a normal way querying that view.
The view would look like:
select Name, IdNumber, Subject1 as Subject, Percentage1 as Percentage, 1 as SubjectNumber
union all
select Name, IdNumber, Subject2 as Subject, Percentage2 as Percentage, 2 as SubjectNumber
...
That should be much easier to deal with.
If this was for production somehow, you should try to set things straight much earlier.
edited Nov 16 '18 at 9:54
answered Nov 16 '18 at 9:42
jhinghausjhinghaus
261517
261517
1
Better switch to UNION ALL
– dnoeth
Nov 16 '18 at 9:51
@dnoeth You're right
– jhinghaus
Nov 16 '18 at 9:53
Thank you Guys for all the assistance. one of the posts helped. but i cant find it now, i think they removed their post
– Kalyn
Nov 16 '18 at 12:09
add a comment |
1
Better switch to UNION ALL
– dnoeth
Nov 16 '18 at 9:51
@dnoeth You're right
– jhinghaus
Nov 16 '18 at 9:53
Thank you Guys for all the assistance. one of the posts helped. but i cant find it now, i think they removed their post
– Kalyn
Nov 16 '18 at 12:09
1
1
Better switch to UNION ALL
– dnoeth
Nov 16 '18 at 9:51
Better switch to UNION ALL
– dnoeth
Nov 16 '18 at 9:51
@dnoeth You're right
– jhinghaus
Nov 16 '18 at 9:53
@dnoeth You're right
– jhinghaus
Nov 16 '18 at 9:53
Thank you Guys for all the assistance. one of the posts helped. but i cant find it now, i think they removed their post
– Kalyn
Nov 16 '18 at 12:09
Thank you Guys for all the assistance. one of the posts helped. but i cant find it now, i think they removed their post
– Kalyn
Nov 16 '18 at 12:09
add a comment |
Thank you Guys for all the assistance. one of the posts helped. but i cant find it now, i think they removed their post
add a comment |
Thank you Guys for all the assistance. one of the posts helped. but i cant find it now, i think they removed their post
add a comment |
Thank you Guys for all the assistance. one of the posts helped. but i cant find it now, i think they removed their post
Thank you Guys for all the assistance. one of the posts helped. but i cant find it now, i think they removed their post
answered Nov 16 '18 at 12:09
KalynKalyn
404
404
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53334654%2fmssql-get-top-4-values-from-12-columns%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
2
Add some sample table data and the expected result - all as formatted text, not images. Consider simplifying the problem, perhaps just 3 subjects will do fine?
– jarlh
Nov 16 '18 at 9:14
2
Why not fix your table structure first? Having repeated groups of columns is a broken design.
– Damien_The_Unbeliever
Nov 16 '18 at 9:30
3
Normalising the schema design would make this sort of query a lot easier. If the person who demands a flat table design is stuck in their ways, perhaps create a view to satisfy them while keeping a sensible design under the hood?
– Diado
Nov 16 '18 at 9:38
3
How they want to have the data presented to them should not dictate how the data is stored.
– Damien_The_Unbeliever
Nov 16 '18 at 9:38
1
If you created that table, change it: Create the table normalized and add a view PIVOting it for the person who requested that result
– dnoeth
Nov 16 '18 at 9:50