如何在MS SQL Server中获得最佳记录组?

时间:2016-08-23 07:29:54

标签: sql sql-server greatest-n-per-group

我有一张学生表和登记表。每个学生可以有多个注册,但只有一个当前注册。如果我想获得学生的当前注册,我必须选择该学生的最高注册记录。

示例查询:

select top 1 enrollmentid
from enrollmenttable 
where enrollmenttable.studentid = studentid
order by enrollmenttable.enrolldate desc 

上述查询返回一名学生的当前注册。我想修改上面的查询,以便我可以检索多个学生的当前注册。即我想为多个学生ID选择前1名记录。

3 个答案:

答案 0 :(得分:0)

您可以使用 override func viewDidLoad() { super.viewDidLoad() let requestURL: NSURL = NSURL(string: "http://ftp.iphoneData@dittodata.host-ed.me/Annotations/testData4.json")! let urlRequest: NSMutableURLRequest = NSMutableURLRequest(URL: requestURL) let session = NSURLSession.sharedSession() let task = session.dataTaskWithRequest(urlRequest) { (data, response, error) -> Void in let httpResponse = response as! NSHTTPURLResponse let statusCode = httpResponse.statusCode if (statusCode == 200) { print("File downloaded.") // print(testData4.json) do{ let json = try NSJSONSerialization.JSONObjectWithData(data!, options:.AllowFragments) if let users = json["users"] as? [[String: AnyObject]] { for user in users { if let name = user["name"] as? String { if let subtitle = user["subtitle"] as? String { print(name,subtitle) } } } } }catch { print("Error with Json: \(error)") } } } task.resume() }

outer apply

请注意,您的查询使用的select e.* from students s outer apply (select top 1 e.* from enrollments e where e.studentid = s.studentid order by enrollmentid desc ) e; 没有TOP。这是一个坏习惯 - 它返回一个任意行,甚至可能在不同的执行中改变。一般情况下,请始终将ORDER BYORDER BY一起使用,除非您真的知道自己在做什么。

答案 1 :(得分:0)

您确实希望在查询中明确地对数据进行排序。我的偏好是这样的;

样本数据

CREATE TABLE #EnrolmentData (StudentID int, EnrolmentID int)
INSERT INTO #EnrolmentData (StudentID, EnrolmentID)
VALUES
(1,1001)
,(1,1002)
,(2,1003)
,(3,1004)
,(3,1005)
,(3,1006)

实际查询

SELECT
a.*
FROM
    (
        SELECT 
        StudentID
        ,EnrolmentID
        ,ROW_NUMBER() OVER(PARTITION BY StudentID ORDER BY StudentID, EnrolmentID) RowNum
        FROM #EnrolmentData
    ) a
WHERE a.RowNum = 1

结果;

StudentID   EnrolmentID RowNum
1           1001        1
2           1003        1
3           1004        1

您可以对其自己运行内部查询以查看它正在做什么(一旦您创建了临时表)。您还没有提到您正在使用的数据类型,因此您需要确保按正确的字段进行排序。如果你想要最高数量的EnrolmentID(并且字段是一个int),那么只需在子查询中加上DESC

使用DESC查询

SELECT
a.*
FROM
    (
        SELECT 
        StudentID
        ,EnrolmentID
        ,ROW_NUMBER() OVER(PARTITION BY StudentID ORDER BY StudentID, EnrolmentID DESC) RowNum
        FROM #EnrolmentData
    ) a
WHERE a.RowNum = 1

结果

StudentID   EnrolmentID RowNum
1           1002        1
2           1003        1
3           1006        1

答案 2 :(得分:0)

使用以下查询获得所需的结果。

WITH cte_enrollment
AS
(
SELECT ROW_NUMBER()OVER(PARTITION BY studentid ORDER BY enrolldate desc) AS RNO ,
   studentid,enrollmentid,enrolldate 
FROM student s
 JOIN enrollmenttable e
            ON e.studentid = s.studentid
)

SELECT  studentid,enrollmentid,enrolldate 
FROM cte_enrollment
WHERE RNO=1