MSSQL从12列中获取前4个值

时间:2018-11-16 09:12:02

标签: 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), (date2), (date3),...) AS value(v)) as [MaxDate]
FROM [YourTableName]

获取其他4个是问题。

4 个答案:

答案 0 :(得分:3)

如果您不想更改表格结构,则需要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)

答案 1 :(得分:1)

数据结构的构建使事情变得更加复杂。 您无权更改。好。 我们需要做一些丑陋的事情来处理这种丑陋的数据结构。

定义一个标准化结构的视图。然后,您可以以正常方式查询该视图。

视图如下:

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
...

这应该更容易处理。

如果这是以某种方式用于生产,则应尝试更早进行设置。

答案 2 :(得分:1)

尝试以the data you have is not normalised取消透视数据,然后再次透视数据。

准备数据:

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

输出:

enter image description here

答案 3 :(得分:1)

谢谢你们的协助。其中一个帖子提供了帮助。但我现在找不到,我认为他们删除了他们的帖子