Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MSSQL从12列中获取前4个值_Sql_Sql Server_Tsql - Fatal编程技术网

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可以将这些列添加到表中。