从sql server中的表中获取前n行

时间:2018-06-15 10:01:45

标签: sql sql-server

所以让我先粘贴两个表架构

CREATE TABLE Segment_Master ( [segment_id] bigint, [subject_code_id] bigint, [segment_name] nvarchar(60), [segment_description] nvarchar(250), [must_attend_question] tinyint, [total_question] tinyint, [branch_id] bigint, [entry_by] bigint, [entry_date] datetime, [test_id] int, [neg_marks_each_quest] decimal(4,2) )
INSERT INTO Segment_Master
VALUES
( 1, 1, N'First Segment', N'First Segment Description', 5, 5, 15, 10238, N'2018-05-16T13:03:17.583', 1, 0.50 ), 
( 2, 1, N'Second Section', N'Second Segment', 5, 6, 15, 10238, N'2018-05-16T13:03:17.583', 1, 0.00 ), 
( 3, 1, N'Third Segment', N'Third Segment', 1, 2, 15, 10238, N'2018-05-16T13:03:17.583', 1, 0.00 )

现在让我展示第二张表..

CREATE TABLE OnlineTestAnswer ( [auto_id] bigint, [segment_id] int, [question_id] int, [marks] decimal(9,4), [student_id] int, [test_id] int, [branch_id] int, [faculty_id] int )
INSERT INTO OnlineTestAnswer
VALUES
( 1, 1, 1, 1.0000, 10246, 1, 15, 10246 ), 
( 2, 1, 31, -0.5000, 10246, 1, 15, 10246 ), 
( 3, 1, 32, -0.5000, 10246, 1, 15, 10246 ), 
( 4, 1, 33, -0.5000, 10246, 1, 15, 10246 ), 
( 5, 1, 34, 0.3700, 10246, 1, 15, 10246 ), 
( 6, 2, 2, 0.0000, 10246, 1, 15, 10246 ), 
( 7, 2, 8, 2.0000, 10246, 1, 15, 10246 ), 
( 8, 2, 31, 0.0000, 10246, 1, 15, 10246 ), 
( 9, 2, 35, 1.0000, 10246, 1, 15, 10246 ), 
( 10, 2, 21, 2.0000, 10246, 1, 15, 10246 ), 
( 11, 2, 22, 2.0000, 10246, 1, 15, 10246 ), 
( 12, 3, 15, 3.5000, 10246, 1, 15, 10246 )

现在如果我在这些表上运行select查询..

enter image description here

现在,如果你能看到没有放大镜:D,有两列: must_attend_question和total_question,顾名思义must_attend_question<=total_question 现在让我运行另一张表,

enter image description here

现在讲述了这个故事, 假设A是一个段,它有5个没有。问题,其中4个问题是强制性的。

现在,如果我给出全部5个答案,那么必须计算前4个。 即如果你看第二张图片,最多没有。第2段的商标将是 7.(2 + 2 + 2 + 1 + 0)注意。这里排名前5位将被计算在内。

我希望w.r.t输出那两张图片,

segment_id|marks
----------|------ 
    1     | -.13
----------|------
   2      |  7
----------|-----
   3      |  3.5

2 个答案:

答案 0 :(得分:3)

您可以使用CROSS APPLY动态获取最高N,然后按标记排序,然后按每个细分进行分组。

SELECT
    T.segment_id,
    SumTopMarks = SUM(S.marks)
FROM
    Segment_Master AS T
    CROSS APPLY (
        SELECT TOP (T.must_attend_question)
            O.*
        FROM
            OnlineTestAnswer AS O
        WHERE
            T.segment_id = O.segment_id
        ORDER BY
            O.marks DESC
    ) AS S
GROUP BY
    T.segment_id

如果您的Segment_Master没有答案而且您希望列出答案,则可以更改CROSS APPLY的{​​{1}}。

答案 1 :(得分:2)

使用row_number和内部查询的解决方案 See working demo

select O.segment_id,
total=Sum(O.marks)
from 
(
select segment_id,marks,
rn=row_number() over(partition by segment_id order by marks desc)
from OnlineTestAnswer) O
join Segment_Master M
on M.segment_id=O.segment_id and O.rn<=M.must_attend_question
group by O.segment_id