1

これは私が以前に尋ねた質問のフォローアップです。

ランク(同点のロジックを含む)をうまく計算できます。問題は、重複ランクの最初のインスタンスに遭遇したときに、将来の重複を検出することです。

結果セットを取得するためのSQLクエリは次のとおりです。

SELECT
    s1.team_id,
    sum(s1.score>s2.score) wins
FROM scoreboard s1
    LEFT JOIN scoreboard s2
        ON s1.year=s2.year
        AND s1.week=s2.week
        AND s1.playoffs=s2.playoffs
        AND s1.game_id=s2.game_id
        AND s1.location<>s2.location
GROUP BY s1.team_id
ORDER BY wins DESC;

これは、PHPでループするサンプルSQL結果セットです。

team_id   wins
--------------
10        52
2         48
5         46
11        46
3         42
9         39
...

これがディスプレイ用の私のPHPコードで、すべてのタイランクに「T-」を追加する必要があります。

$i = 0;
while($row = mysql_fetch_assoc($r)) { //iterate thru ordered (desc) SQL results
    ++$i;
    ($row['wins'] == $prev_val)
        ? $rnk = 'T-' . $rnk    //same as previous score, indicate tie
        : $rnk = $i;            //not same as previous score
    $rnk = str_replace('T-T-','T-',$rnk); //eliminate duplicative tie indicator
    if ($row['team_id'] == $team_id) { //current team in resultset matches team in question, set team's rank
        $arr_ranks['tp']['cat'] = 'Total Wins';
        $arr_ranks['tp']['actual'] = number_format($row['wins'],1);
        $arr_ranks['tp']['league_rank'] = $rnk;
        $arr_ranks['tp']['div_rank'] = $div_rnk;
    }
    else if ($i == 1) { //current team is category leader (rank=1) and is not team in question, set current team as leader
        $arr_ranks['tp']['leader'] = "<a href='index.php?view=franchise&team_id=" . $row['team_id'] . "'>" . get_team_name($row['team_id']) . '</a> (' . number_format($row['wins']) . ')';
    }
    $prev_val = $row['wins']; //set current score as previous score for next iteration of loop
}

上記の「タイ」ロジックは、チーム#4をチーム#3とタイしたものとしてキャプチャしますが、その逆はありません

つまり、チーム#3の場合$rnk = 3は、、チーム#4の場合は$rnk = T-3。(どちらも「T-3」である必要があります。)

したがって、問題は次のようになります。結果を繰り返し処理しながら、現在のスコアがリストのさらに下のスコアの同点/重複であるかどうかを確認するために「先読み」して、後続の重複と一緒に同点として扱うことができるようにするにはどうすればよいですか。

@Airzookaは私に潜在的な解決策を与えてくれましたが、それを行うためのより効率的な方法があるかどうか知りたいです(おそらくSQLレベルでも)。

ありがとう。

4

5 に答える 5

1

擬似コード:

loop through rows as row1
    loop through rows as row2
        if row1 ain't row2 and row1.points == row2.points, append T    

アップデート:

とにかく、結果セットを wins で並べ替えているので、これはどうですか: 各行に関する情報を 、 などの一時配列または変数に格納してみてください$previousTeamWins$previousTeamName次に、現在と前を比較して T を割り当てることができます。それに基づいて。したがって、次の反復まで(または最終行の場合はループの終了まで)、割り当てを効果的に遅らせています。行セットを 1 回移動するだけで、作業が完了するはずです。

于 2012-06-12T19:39:29.047 に答える
0

これはどうですか?

SELECT
 t1.*,
 EXISTS (
  SELECT *
  FROM `teams` as t2
  WHERE t2.pts = t1.pts AND t1.id != t2.id
 ) as `tied`
 FROM `teams` as t1
...
于 2012-06-12T17:50:42.340 に答える
0

SQL経由で解決策を見つけたと思います!エレガントではないかもしれませんが(後でクリーンアップできます)、ここに行きます...

クエリ:

SELECT a.team_id, a.wins, count(*) instances
FROM
    (SELECT
        s1.team_id,
        sum(s1.score>s2.score) wins
    FROM scoreboard s1
        LEFT JOIN scoreboard s2
            ON s1.year=s2.year
            AND s1.week=s2.week
            AND s1.playoffs=s2.playoffs
            AND s1.game_id=s2.game_id
            AND s1.location<>s2.location
    GROUP BY s1.team_id) AS a
    LEFT JOIN
        (SELECT
            sum(s1.score>s2.score) wins
        FROM scoreboard s1
            LEFT JOIN scoreboard s2
                ON s1.year=s2.year
                AND s1.week=s2.week
                AND s1.playoffs=s2.playoffs
                AND s1.game_id=s2.game_id
                AND s1.location<>s2.location
        GROUP BY s1.team_id) AS b
            ON a.wins = b.wins
GROUP BY a.team_id, b.wins
ORDER BY a.wins DESC;

これにより、出力が得られます...

=================================
|team_id   | wins    |instances |
=================================
|10        | 44      |1         |
|2         | 42      |3         | //tie
|9         | 42      |3         | //tie
|5         | 42      |3         | //tie
|3         | 41      |1         |
|11        | 40      |1         |
|...       |         |          |
=================================

次に、PHP で when をチェックすることで、すべての関係を検出できるようになります$row['instances'] > 1

この不自然に面倒な問題に付き合ってくれてありがとう!

于 2012-06-13T16:52:57.823 に答える
0

おい、まだあなたのコードを見ている。結局のところ、1 つまたは 2 つのチームだけを出力したいということですね。リーダーが問題のチームである場合は 1 つ、それ以外の場合は 2 つです。その場合は、次のようなことを試してください (テストされていないという警告が表示されます)。

$i = 0;
while($row = mysql_fetch_assoc($r)) { //iterate thru ordered (desc) SQL results 
    ++$i; 
    ($row['wins'] == $prev_wins) 
        ? $rnk = $prev_rnk    //same as previous score, indicate tie 
        : $rnk = $i;            //not same as previous score 
    $rnk = str_replace('T-T-','T-',$rnk); //eliminate duplicative tie indicator 

    if ($prev_team_id == $team_id) {
        $arr_ranks['tp']['cat'] = 'Total Wins'; 
        $arr_ranks['tp']['actual'] = number_format($prev_wins,1); 
        $arr_ranks['tp']['league_rank'] = $prev_rnk; 
        $arr_ranks['tp']['div_rank'] = $div_rnk;

        if ($row['wins'] == $prev_wins)
        {
            $arr_ranks['tp']['tie'] = true;
        }
        else
        {
            $arr_ranks['tp']['tie'] = false;
        }

    break;
    }
    else if ($i == 1) { //current team is category leader (rank=1) and is not team in question, set current team as leader 
        $arr_ranks['tp']['leader'] = "<a href='index.php?view=franchise&team_id=" . $row['team_id'] . "'>" . get_team_name($row['team_id']) . '</a> (' . number_format($row['wins']) . ')'; 
    }

    $prev_wins = $row['wins'];
    $prev_team_id = $row['team_id'];
    $prev_rnk = $rnk;
}

if ($prev_team_id == $team_id) {
    $arr_ranks['tp']['cat'] = 'Total Wins'; 
    $arr_ranks['tp']['actual'] = number_format($prev_wins,1); 
    $arr_ranks['tp']['league_rank'] = $prev_rnk; 
    $arr_ranks['tp']['div_rank'] = $div_rnk;

    if ($row['wins'] == $prev_wins)
    {
        $arr_ranks['tp']['tie'] = true;
    }
    else
    {
        $arr_ranks['tp']['tie'] = false;
    }

}
于 2012-06-12T20:27:18.397 に答える
0

これを試してみてください

SELECT t1.`id`,t1.`pts`,t1.`team_id`,
IF(t1.`pts` = t2.`pts` AND t1.`id` != t2.`id` ,1,0) AS `tied`
FROM `teams` t1
LEFT JOIN `teams` t2 on t2.`pts` = t1.`pts` AND t2.`id` != t1.`id`
GROUP bY t1.`id`
于 2012-06-12T18:18:10.747 に答える