【问题标题】:NHL standings in SQLSQL 中的 NHL 排名
【发布时间】:2015-12-26 10:39:50
【问题描述】:

我有一个 SQL 查询,它根据旧的 NHL 格式生成球队排名。

代码的第一部分获取每个分区的前 3 名球队,第二部分获取其余部分并对它们进行排序按点/差。

可以在这里看到:http://rgmgstandings.tk

这是我的 SQL 查询:

("(SELECT *, 1 as `SortKey` from `standings_east` 
        WHERE pts = (select max(pts) 
            from standings_east as t 
    where t.`div` = standings_east.`div`))

UNION ALL 

(select *, 2 as SortKey from `standings_east` 
        where team not in 
            (select team from standings_east 
                where pts = (select max(pts) 
                    from standings_east as t 
                        where t.`div` = standings_east.`div`))) 
        order by SortKey, pts desc, diff desc") 

如果您访问我的网站并查看西部联盟的排名(蓝色横幅),您会注意到“CEN”中有 3 支球队得分相同(芝加哥、温尼伯、哥伦布)

我希望查询仅根据拥有最多“胜/胜”的球队从该部门中选择一支球队。

正确的排名应该是:

埃德蒙顿 (NW) 80
阿纳海姆 (PAC) 74
哥伦布 (CEN) 71
达拉斯 (PAC) 73
芝加哥 (CEN) 71
温尼伯 (CEN) 71

我怎样才能做到这一点?

【问题讨论】:

  • 您可以使用与 pts 相同的原理来获得胜利,例如 `AND w = (select max(w) from .....)`
  • ...如果两队积分相同并且获胜会怎样?
  • 显示带有架构和数据的 sqlfiddle.com。
  • @Clockwork-Muse 将有第三个声明,谁有更大的差异 (DIFF)
  • 这是一个 sqlfiddle @Drew sqlfiddle.com/#!2/f377e7/5/0

标签: mysql sql sorting


【解决方案1】:

查询

select team,`div`,pts,1 as sortOrder 
from 
(   -- note use parentheses to avoid mysql error 1221
    (select team,`div`,pts,@cen:=team from `standings_west` where `div`='CEN' order by pts desc limit 1) 
    union all 
    (select team,`div`,pts,@pac:=team from `standings_west` where `div`='PAC' order by pts desc limit 1) 
    union all 
    (select team,`div`,pts,@nw:=team from `standings_west` where `div`='NW' order by pts desc limit 1) 
) xDerived1 
cross join (select @cen='',@pac='',@nw='') params 
union 
select team,`div`,pts,sortOrder 
from 
(   select team,`div`,pts,2 as sortOrder 
    from `standings_west` 
    where team!=@cen and team!=@pac and team!=@nw 
    order by pts desc 
    limit 3 
) xDerived2 
order by sortOrder,pts desc;

结果

+----------+-----+-----+-----------+
| team     | div | pts | sortOrder |
+----------+-----+-----+-----------+
| EDMONTON | NW  |  80 |         1 |
| ANAHEIM  | PAC |  74 |         1 |
| WINNIPEG | CEN |  71 |         1 |
| DALLAS   | PAC |  73 |         2 |
| CHICAGO  | CEN |  71 |         2 |
| COLUMBUS | CEN |  71 |         2 |
+----------+-----+-----+-----------+

存储过程

以下描述了一个存储过程,只是为了在您遇到问题并需要它时显示它。

drop procedure if exists xdoit;
delimiter $$
create procedure xdoit()
begin
select team,`div`,pts,1 as sortOrder 
from 
(   -- note use parentheses to avoid mysql error 1221
    (select team,`div`,pts,@cen:=team from `standings_west` where `div`='CEN' order by pts desc limit 1) 
    union all 
    (select team,`div`,pts,@pac:=team from `standings_west` where `div`='PAC' order by pts desc limit 1) 
    union all 
    (select team,`div`,pts,@nw:=team from `standings_west` where `div`='NW' order by pts desc limit 1) 
) xDerived1 
cross join (select @cen='',@pac='',@nw='') params 
union 
select team,`div`,pts,sortOrder 
from 
(   select team,`div`,pts,2 as sortOrder 
    from `standings_west` 
    where team!=@cen and team!=@pac and team!=@nw 
    order by pts desc 
    limit 3 
) xDerived2 
order by sortOrder,pts desc;
end$$
delimiter ;

调用存储过程

call xdoit();

这里有几个厘米。

首先,您的 sqlfiddle 有来自西方的数据,但有来自东方的查询。根据表名,我建议您将所有数据放在一个表中,而不是两个表中,并为东或西设置一列。

该查询使用交叉连接来仅建立用于获取部门领导的变量,以便将这些部门领导排除在 sortOrder=2 团队之外。

根据需要调整抢七局(即:获得 71 分的球队)关于您在 cmets 中对 @Clockwork 实施 DIFF 的必要性

如果您有任何问题,请询问。


以下是我根据您在该聊天室发表的评论为您提出的 multi_query php 解决方案。

我能想出的唯一解决方案是以下基于显然结果以两个结果集返回的结果。因此由next_result() 驱动的while 循环。第一个结果集有前 3 行,第二个结果集有后面的 12 行。这正是 PHP 的看法。

还要注意,在 PHP 部分,由于我似乎在处理 multi_query,因此我利用了这一点并将 mysql 参数传递给而不是通过 cross join 来获取它们。

PHP

<!DOCTYPE html>
<html lang="en">
<head>
  <title>RGMG: Standings</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
  <script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
</head>
<body>

<?php 
    //mysqli_report(MYSQLI_REPORT_ALL);
    mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
    error_reporting(E_ALL); // report all PHP errors
    ini_set("display_errors", 1); 

    try {
        $mysqli= new mysqli('localhost', 'dbUser', 'thePassword', 'theDbName'); 

        echo "<table><div><br><br>";    // note you had this line a little bit wrong


        // notice below the concat of the $sql and the multi_query()
        $sql = "set @cen:='',@pac:='',@nw:=''; ";
        $sql .= "select *
                from
                (   select team,`div`,gp,win,lose,otl,goalsF,goalsA,diff,gpg,gaa,pts,1 as sortOrder 
                    from 
                    (   -- note use parentheses to avoid mysql error 1221
                        (select team,`div`,gp,win,lose,otl,goalsF,goalsA,diff,gpg,gaa,pts,@cen:=team from `standings_west` where `div`='CEN' order by pts desc, win desc, diff desc limit 1) 
                        union all 
                        (select team,`div`,gp,win,lose,otl,goalsF,goalsA,diff,gpg,gaa,pts,@pac:=team from `standings_west` where `div`='PAC' order by pts desc, win desc, diff desc limit 1) 
                        union all 
                        (select team,`div`,gp,win,lose,otl,goalsF,goalsA,diff,gpg,gaa,pts,@nw:=team from `standings_west` where `div`='NW' order by pts desc, win desc, diff desc limit 1) 
                    ) xDerived1 
                    union all
                    select team,`div`,gp,win,lose,otl,goalsF,goalsA,diff,gpg,gaa,pts,sortOrder 
                    from 
                    (   select team,`div`,gp,win,lose,otl,goalsF,goalsA,diff,gpg,gaa,pts,2 as sortOrder 
                        from `standings_west` 
                        where team!=@cen and team!=@pac and team!=@nw 
                        order by pts desc 
                    ) xDerived2
                ) xDerived3 
                order by sortOrder,pts desc";

        echo "<div class='container'>";
        echo "<img src='http://i.imgur.com/sjDHhIV.png' width='100%' alt='West'>";
        echo "<table class='table table-condensed'>
        <tr class='top'>
        <th class='rank'></th>
        <th class='team'>TEAM</th>
        <th>DIV</th>
        <th>GP</th>
        <th>W</th>
        <th>L</th>
        <th class='otl'>OTL</th>
        <th class='pts'>PTS</th>
        <th>GF</th>
        <th>GA</th>
        <th>DIFF</th>
        <th>GPG</th>
        <th>GAA</th>
        ";
        $counter=1;
        $mysqli->multi_query($sql);
        while(true) {
            if ($result = $mysqli->store_result()) {
                while ($row = $result->fetch_assoc()) {
                    $gpg = ($row['goalsF']);
                    $gaa = ($row['goalsA']);

                    if ($row['gp'] != 0 ){
                        $gpg = ($row['goalsF'] / $row['gp']);
                        $gaa = ($row['goalsA'] / $row['gp']);
                    }
                    else {
                        $row['gp'] = "";
                    }

                    echo "<tr>
                        <td class='rank'>" . "$counter" . "</td>
                        <td class='team'>" . $row['team'] . "</td>
                        <td>" . $row['div'] . "</td>
                        <td>" . $row['gp'] . "</td>
                        <td>" . $row['win'] . "</td>
                        <td>" . $row['lose'] . "</td>
                        <td class='otl'>" . $row['otl'] . "</td>
                        <td class='pts'>" . $row['pts'] . "</td>
                        <td>" . $row['goalsF'] . "</td>
                        <td>" . $row['goalsA'] . "</td>
                        <td>" . $row['diff'] . "</td>
                        <td>" . round($gpg, 2) . "</td>
                        <td>" . round($gaa, 2) . "</td>";
                    $counter++;
                }
                $result->free();
            }
            if ($mysqli->more_results()) {
                $mysqli->next_result();
            }                   
            else {
                break;
            }   
        }
        echo "</table></div>";

        $mysqli->close();
    } catch (mysqli_sql_exception $e) { 
        throw $e; 
    }

?>

</body>
</html>

【讨论】:

  • 非常感谢德鲁!正如你提到的,我对其进行了一些修改,并且它在小提琴中工作。但由于某种原因,在我的网站上,它只显示前 3 行,联盟似乎没有工作。 sqlfiddle.com/#!2/f377e7/31 || rgmgstandings.tk
  • 好吧,我再考虑一下。顺便说一句,这很有趣,因为 NHL 是我兄弟的全部生命和呼吸,我希望他也一样。他是一个体育数据有点极端的类型。随时通知我(我想主要在我的mysql chat room on the stack
【解决方案2】:

首先我喜欢 NHL,根据您的查询,我们可以说您向我们展示的表格是排名东,所以让我们试试这个:

    select team,DIV,GP,W,L,OTL,PTS,GF,GA,DIFF,GPG,GAA,1 as sort_key 
      from standings_east t
      where exists 
       (select 1 
          from 
           (select DIV,max(PTS) as PTS,max(W) as W from standings_east 
              group by DIV) a 
          where t.DIV=a.DIV and t.PTS=a.PTS and t.W=a.W
       )
   UNION ALL
   select team,DIV,GP,W,L,OTL,PTS,GF,GA,DIFF,GPG,GAA,2 as sort_key 
     from standings_east t
     where not exists 
       (select 1 
          from 
           (select DIV,max(PTS) as PTS,max(W) as W from standings_east 
              group by DIV) a 
        where t.DIV=a.DIV and t.PTS=a.PTS and t.W=a.W
       )
  order by sort_key,PTS DESC

我认为有一些更好的方法,但这是最像你的方法,也是最容易理解的方法,只需在你的代码上添加一个 group by 并祝圣诞快乐

【讨论】:

  • 嘿,谢谢我的人,我可能应该提供一个 sqlfiddle 开头:sqlfiddle.com/#!2/f377e7/5/0 祝你圣诞快乐!
  • 哦,我已经这样做了,但我不知道如何将 sqlfiddle 编辑到这里。你可以检查我的我认为这是你想要的:) sqlfiddle.com/#!9/a6003/4
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-14
  • 1970-01-01
  • 1970-01-01
  • 2014-03-28
  • 1970-01-01
相关资源
最近更新 更多