MSSQL从12列中获取前4个值
我需要一些帮助。我的结果集如下所示:MSSQL从12列中获取前4个值,sql,sql-server,tsql,Sql,Sql Server,Tsql,我需要一些帮助。我的结果集如下所示: Name | IdNumber | Subject1 |Percentage | Subject2 | Percentage | Subject3 | Percentage | (...until subject 12) 我只需要返回学生在考试中得分最高的4个科目及其百分比 每个学生获得最高分数很容易,我是这样做的: SELECT [Other Fields], (SELECT Max(v) FROM (VALUES (date1), (dat
Name | IdNumber | Subject1 |Percentage | Subject2 | Percentage | Subject3 | Percentage | (...until subject 12)
我只需要返回学生在考试中得分最高的4个科目及其百分比
每个学生获得最高分数很容易,我是这样做的:
SELECT [Other Fields],
(SELECT Max(v)
FROM (VALUES (date1), (date2), (date3),...) AS value(v)) as [MaxDate]
FROM [YourTableName]
获取其他4是个问题。数据结构的构建方式使事情变得更加复杂。 你不允许改变这一点。好啊 我们需要做一些丑陋的事情来处理这种丑陋的数据结构 定义规范化结构的视图。然后,您可以以正常的方式查询该视图 该视图看起来像:
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
...
这应该更容易处理
如果这是为了生产,你应该尽量早点把事情弄清楚。如果你不想改变你的表格结构,那么你需要
UNPIVOT
数据,然后你可以选择前4个主题
;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)
尝试取消pivot数据为,然后再次透视数据
准备数据:
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
取消驱动数据和数据透视:
;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
输出:
添加一些示例表数据和预期结果-全部为格式化文本,而不是图像。考虑简化问题,也许只有3个主题会做得很好?为什么不先修改表结构?拥有重复的列组是一种破坏性的设计。规范化模式设计将使这种查询更容易。如果要求平面表格设计的人陷入了困境,也许可以创建一个视图来满足他们的要求,同时保留一个合理的设计?他们希望如何向他们展示数据不应该决定数据的存储方式。如果您创建了该表格,更改:创建规范化的表,并为请求将resultBetter切换到UNION all的人添加一个视图,使其旋转感谢大家的帮助。其中一个帖子起了作用。但我现在找不到它,我想他们删除了他们的帖子。谢谢你让我了解PIVOT和UNPIVOT操作符。:-)在这里,在结果集中旋转数据时,我们需要考虑所有12个组合,因为前4个主题对于每个都是不同的。student@SanalSunnyOP可以将这些列添加到表中。