为另一列的每个值选择一列的前 1 个

Selecting the top 1 of one column, for each value of another column

我们有中学生报告周期。我正在尝试编写一个查询,该查询将创建一个简洁的小 table 显示我们每个中学学年的最新报告周期。

我找到了一种方法来显示我想要的内容,但它使用了 UNION 并且似乎应该有一种更有效的方法来实现它。

所以目前我重复使用了 7 次,更改了 WHERE 子句,因此 SchoolYear 更改为我们需要的每个(7 到 13):

SELECT *
FROM 
    (SELECT TOP 1
    CycleAllocations.ReportCycle,
    CycleAllocations.SchoolYear,
    CycleDetails.ReportName
FROM CycleAllocations
LEFT OUTER JOIN CycleDetails
ON CycleAllocations.ReportCycle = CycleDetails.ReportCycle 
WHERE SchoolYear = 7
ORDER BY intReportCycle DESC) AS CYCLE7
UNION
SELECT *
FROM 
    (SELECT TOP 1
    CycleAllocations.ReportCycle,
    CycleAllocations.SchoolYear,
    CycleDetails.ReportName
FROM CycleAllocations
LEFT OUTER JOIN CycleDetails
ON CycleAllocations.ReportCycle = CycleDetails.ReportCycle 
WHERE SchoolYear = 8
ORDER BY intReportCycle DESC) AS CYCLE8
UNION... etc etc

这会产生这样的 table:

ReportCycle SchoolYear ReportName
173 7 Short Report March 2021
173 8 Short Report March 2021
173 9 Short Report March 2021
173 10 Short Report March 2021
174 11 Yr11 Mock Exams Jan 2021
172 12 Long Report March 2021
175 13 U6 Mock Exams Jan 2021

有没有更好的写法?

您可以试试这个,它可能需要调整,因为您还没有共享您的 table 架构或任何示例数据。

使用行号函数对排序的行进行编号,以便您的 top1 行获得编号 1 并为每个学年的每个“分区”重复该操作,然后仅 return 具有编号的行1.

我也使用了 table 别名,这使得查询更加简洁易读。

    select ReportCycle, SchoolYear, ReportName from (
        select ca.ReportCycle, ca.SchoolYear, cd.ReportName, Row_Number() over (partition by schoolyear order by intReportCycle desc )
        from CycleAllocations ca
        left join CycleDetails cd on ca.ReportCycle = cd.ReportCycle 
    )x
    where rn=1
order by SchoolYear