计算SQL中的排名

时间:2015-09-08 00:33:29

标签: mysql sql

我有一张浮动得分表,我想将它们从最大到最小排名,如果得分相同,排名相同。我正在使用MySQL / MySQL Workbench,并且赞赏任何好的想法。

以下是输入和输出示例

String hdrSql = "insert into Header "
    + "(request_id, order_id, user_id) values (0, ?, ?)";
String dtlSql = "insert into Detail "
    + "(request_id, order_id, line_no, comment) values (?, ?, ?, ?)";
PreparedStatement header = null, details = null;
int rows = 0;
long orderId = request.getOrderId();    // request is an object parameter
try {
    header = connection.prepareStatement(hdrSql, Statement.RETURN_GENERATED_KEYS);
    header.setAutoCommit(false);
    header.setLong(1, orderID);
    header.setString(2, request.getUserId());
    rows = header.executeUpdate();
    ResultSet rs = header.getGeneratedKeys();
    if (!rs.next()) {
        log("Could not get next request_id");   // This statement logged.
        return false;                       // But no exception thrown.
    }
    int requestId = rs.getInt("request_id");

    details = connection.prepareStatement(dtlSql);
    details.setInt(1, requestId);
    details.setLong(2, orderId);
    for (Item item : request.getItems()) {
        details.setInt(3, item.getLineNumber());
        details.setString(4, item.getComment());
        rows += details.executeUpdate();
    }
    // Should have inserted 1 row for header, plus 1 row for each item
    return rowsInserted == request.getItems().size() + 1;
} catch (SQLException sqle) {
    log("Database error" + sqle.getMessage());
    throw sqle;
} finally {
    try {       // Commit or roll back, depending on status:
        if (rows == request.getItems().size() + 1) {
            header.commit();
        } else {
            header.rollback();
            log("Rolled back request");     // This gets logged, too.
        }
        if (header != null) header.close();
        if (details != null) details.close();
    } catch (SQLException sqle) { sqle.printStackTrace(); }

尝试了以下查询,但由于它不处理重复,

无法正常工作
+----+-------+
| Id | Score |
+----+-------+
| 1  | 3.50  |
| 2  | 3.65  |
| 3  | 4.00  |
| 4  | 3.85  |
| 5  | 4.00  |
| 6  | 3.65  |
+----+-------+

+-------+------+
| Score | Rank |
+-------+------+
| 4.00  | 1    |
| 4.00  | 1    |
| 3.85  | 2    |
| 3.65  | 3    |
| 3.65  | 3    |
| 3.50  | 4    |
+-------+------+

在上面的查询中,用户3和用户5具有相同的得分值4,但排名不同。

我还尝试了以下查询来仅对得分进行排名,并返回非常奇怪的结果,

SELECT    id, score,
          @curRank := @curRank + 1 AS rank
FROM      TestRank tr, (SELECT @curRank := 0) r
ORDER BY  score desc;

enter image description here

提前谢谢, 林

2 个答案:

答案 0 :(得分:2)

你可以通过“记住”上一个分数来做到这一点:

SELECT id, score,
       (@curRank := if(@s = score, @curRank + 1,
                       if(@s := score, 1, 1)
                      )
       ) as rank
FROM TestRank tr CROSS JOIN
     (SELECT @curRank := 0, @s := -1) r
ORDER BY score desc;

答案 1 :(得分:2)

看看这个小提琴:http://sqlfiddle.com/#!9/17a49/3

以下是适合您的查询:

Database

在" scores_and_ranks"在内部查询中,我们总计了比当前分数更好的不同分数。最高分将为零,因此我们加1以获得您想要的等级值。

我们必须加入该表的原因(使用表" s")是为了确保重复的得分值(例如,得分= 4的两行)以不同的行显示。 / p>