drdl18946 2014-04-16 15:57
浏览 79
已采纳

查询为两个唯一字段中的每一个选择具有特定ID的行并计算第三字段的位置

My relevant table structure is like so (with id being primary key and having autoincrement):

id | pid | type | distance | pspeed

Each pid (player id) has a unique row for every type and pspeed combination. For example, there is no row with a specific pid value, a specific type value, and more than one pspeed value. Likewise for pid and pspeed, there is not more than one row with the same type value.

My goal is to, for every type (there are 26 total), group by pspeed (there are 7 different pspeed values) and sort by distance descending until a specific pid value is found and return that row with the "rank" or "position" of that row. Basically I want to do a ORDER BY distance for each type and pspeed until a specific pid value is reached.

Is this possible via pure queries? I know how to do this with several queries and loops in a PHP script but I would like to be able to minimize the code I have to write. Unfortunately, I'm quite positive it would require SQL knowledge that is beyond me.

If counting up until a specific pid value is not possible I can just bake that into my PHP script to determine the "rank".


Edit: here is how I'm currently doing this (using CodeIgniter):

$res = array();
$q1 = $this->db1->get_where('uq_players', array('authid' => $authid), 1);
if($q1->num_rows()){
    foreach($this->jtype as $type => $value){
        foreach($this->pspeed as $speed){
            $i = 0;
            $this->db1->order_by('distance', 'desc');
            $q2 = $this->db1->get_where('uq_jumps', array('type' => $type, 'pspeed' => $speed));
            foreach($q2->result() as $row){
                $i += 1;
                if($row->pid === $q1->row()->id){
                    $res[] = self::create_array($row, $type, $row->wpn, $i);
                    break;
                }
            }
        }
    }
}

And some sample data.

  • 写回答

1条回答 默认 最新

  • doubinchou4219 2014-04-16 16:58
    关注

    You can first try geting a rowset of all different scores for a given player and all combinations of type and pspeed, then left join all other scores with the same type and pspeed but greater distance. If your player is ranked first for this combination you will get one row with nulls, otherwise you will get number of rows equal to number of players with greater distance, which incremented will give you the players rank.

    SELECT t1.type, t1.pspeed, 1+SUM(t2.pid IS NOT NULL) as rank
    FROM scores t1
    LEFT JOIN scores t2 
      ON t1.type = t2.type AND t1.pspeed = t2.pspeed AND t1.distance < t2.distance
    WHERE t1.pid = 1
    GROUP BY t1.type, t1.pspeed
    

    See Sqlfiddle example.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥20 基于MSP430f5529的MPU6050驱动,求出欧拉角
  • ¥20 Java-Oj-桌布的计算
  • ¥15 powerbuilder中的datawindow数据整合到新的DataWindow
  • ¥20 有人知道这种图怎么画吗?
  • ¥15 pyqt6如何引用qrc文件加载里面的的资源
  • ¥15 安卓JNI项目使用lua上的问题
  • ¥20 RL+GNN解决人员排班问题时梯度消失
  • ¥60 要数控稳压电源测试数据
  • ¥15 能帮我写下这个编程吗
  • ¥15 ikuai客户端l2tp协议链接报终止15信号和无法将p.p.p6转换为我的l2tp线路