【问题标题】:SQL Query to return maximums over decadesSQL 查询返回几十年的最大值
【发布时间】:2012-10-15 21:12:46
【问题描述】:

这是使用 MYSQL 我的问题如下。我有一个棒球数据库,在那个棒球数据库中有一个主表,其中列出了每个曾经打过球的球员。还有一个击球台,可以跟踪每个球员的击球数据。我创建了一个将这两者结合在一起的视图;因此masterplusbatting 表。 我现在想找到自棒球开始以来每十年中 HR 最高的击球手。这是我尝试过的。

    select f.yearID, truncate(f.yearid/10,0) as decade,f.nameFirst, f.nameLast, f.HR
    from (
    select yearID, max(HR) as HOMERS
    from masterplusbatting group by yearID
    )as x inner join masterplusbatting as f on f.yearID = x.yearId and f.HR = x.HOMERS
    group by decade

您可以看到我截断了 yearID 以获取 187, 188, 189 等而不是 1897, 1885,。然后我按十年分组,认为这会给我每十年最高的值,但它没有返回正确的值。例如,它给了我 Adrian Beltre 在 2004 年的 48 HR,但每个人都知道 Barry Bonds 在 2001 年达到了 73 HR。谁能给我一些建议?

【问题讨论】:

  • 您需要按“十年”而不是年份分组。这可能是数据问题 - 或者您需要先对日期进行更多数学运算
  • 这是什么类型的 SQL?对于不同的供应商和实现,可用的功能是不同的......
  • 离题,但“每个人都知道巴里·邦兹在 2001 年达到 73 小时”对我来说似乎相当乐观(尤其是考虑到这里的观众)
  • 正式注明。 :) 下次发帖之前我会考虑的。
  • 那个视图的名字几乎无意中很搞笑。

标签: mysql sql


【解决方案1】:
SELECT
  Lookup.DecadeID,
  Data.*
FROM
(
  SELECT
    truncate(yearid/10,0) as decadeID,
    MAX(HR) as Homers
  FROM
    masterplusbatting
  GROUP BY
    truncate(yearid/10,0)
)
  AS lookup
INNER JOIN
  masterplusbatting AS data
    ON  data.yearid >= lookup.decadeID * 10
    AND data.yearid <  lookup.decadeID * 10 + 10
    AND data.HR     =  lookup.homers

为 MySQL 编辑

【讨论】:

  • 对不起,我想这对我没有帮助,因为我认为 WITH 在 MySQL 中不起作用。还是谢谢。
  • @abrahamlincoln:为 MySql 编辑。如果有任何拼写错误等,仍然在 iPhone 上道歉
【解决方案2】:

您的查询似乎是由错误的事物聚合而成。在某个地方,我希望看到基于玩家的分组。

select truncate(mpb.yearid/10, 0) as decade, mpb.nameFirst, mpb.nameLast, sum(mpb.HR) as HRs
from masterplusbatting mpb
group by truncate(mpb.yearid/10, 0), mpb.nameFirst, mpb.nameLast

这给出了每十年的本垒打总数。现在,你想要拥有最多的人。为此,我将使用row_number() 函数和子查询:

select decade, nameFirst, nameLast, HRs
from (select decade, nameFirst, nameLast, HRs,
             row_number() over (partition by decade order by HRs desc) as seqnum
      from (select truncate(mpb.yearid/10, 0) as decade, mpb.nameFirst, mpb.nameLast, sum(mpb.HR) as HRs
            from masterplusbatting mpb
            group by truncate(mpb.yearid/10, 0), mpb.nameFirst, mpb.nameLast
           ) t
     ) t
where seqnum = 1
order by 1

在 MySQL 等数据库中,您需要通过第二次连接来执行此操作:

select t.*
from (select truncate(mpb.yearid/10, 0) as decade, mpb.nameFirst, mpb.nameLast, sum(mpb.HR) as HRs
      from masterplusbatting mpb
      group by truncate(mpb.yearid/10, 0), mpb.nameFirst, mpb.nameLast
     ) t join
     (select decade, max(HRs) as maxHRs
      from (select truncate(mpb.yearid/10, 0) as decade, mpb.nameFirst, mpb.nameLast, sum(mpb.HR) as HRs
            from masterplusbatting mpb
            group by truncate(mpb.yearid/10, 0), mpb.nameFirst, mpb.nameLast
           ) t
      group by decade
     ) tsum
     on t.decade = tsum.decade and t.HRs = tsum.maxHRs
order by decade

【讨论】:

  • 感谢您的回复。我是 mysql 新手,对row_number() over 一无所知,它给了我一个语法错误。知道为什么会这样吗?
  • MySQL,很抱歉没有在原始问题中指出这一点。
  • 哦,那是一个不支持排名功能的数据库。唉。
  • 在tstum.maxHRs 上仍然给我一些语法错误。我会玩一下,看看我能不能让它工作。非常感谢。
猜你喜欢
  • 2021-02-09
  • 2019-08-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-03
  • 1970-01-01
相关资源
最近更新 更多