【问题标题】:SQL can't get head around logicSQL 无法理解逻辑
【发布时间】:2012-09-19 11:02:35
【问题描述】:

我有一个具有以下架构的板球数据库:

Bowl(BowlID, MatchID, Striker, Non-Striker, Bowler, Runs, OverNum)
 - Stores info for every ball
Match(MatchID, Team1, Team2, Date)
 - Stores all the matches

我正在尝试计算一场比赛的倒数第二个球中有多少百分比得分。

所以首先我需要拿到每场比赛的倒数第二个球。我真的不知道该怎么做。 OverNum 列存储了球号,因此对于 2020 场比赛,这将从“0.1”开始到“19.6”(假设他们坚持了几局)。

会不会是这样的:

SELECT MatchID, MAX(OverNum) 
FROM Bowl 
WHERE OverNum 
NOT IN (SELECT Max(OverNum) FROM Bowl)
GROUP BY MatchID

我无法确保它从每场比赛中获得倒数第二,而不是从整个碗桌中获得第二高的 OverNum...

【问题讨论】:

  • 你怎么知道比赛是 20-over 一还是 50-over 一?
  • 你的内部选择语句应该是:(SELECT Max(OverNum) FROM Bowl b2 WHERE b2.MatchID = MatchID)

标签: sql hsqldb


【解决方案1】:

我正在尝试计算一场比赛的倒数第二个球中有多少百分比得分。

以下几行:

SELECT 
    -- Consider each case where the runs scored on the
    -- penultimate ball is what you wanted as a '1' and rest as '0'
    (SUM(CASE Runs 
        WHEN @needed THEN 1
        ELSE 0
    END) * 100) / SUM(1),
FROM 
    Bowl b1
    JOIN 
    (
        // Penultimate ball in a given match.
        SELECT bNextMax.MatchId, Max(CONVERT(REAL, bNextMax.OverNum)) 
        FROM 
            Bowl bNextMax
            JOIN (
                SELECT MatchId, MAX(CONVERT(REAL, OverNum)) OverNum
                FROM Bowl 
                GROUP BY MatchID
            ) as bMax
            ON bNextMax.MatchID = bMax.MatchID AND bNextMax.OverNum != bMax.OverNum
    ) b2
    ON b1.MatchID = b2.MatchID AND b1.OverNum = b2.OverNum

【讨论】:

  • 谢谢,这给了我一个很好的百分比基础!但是我想我会使用下面的评论来获得倒数第二个球,因为这考虑到倒数第二个球是 10.4 号球的情况。 (也许他们只打了 20 次中的 11 次)
  • 对,有道理,我在推断最后一个球时没有考虑到这一点。
  • @DuaneAllman,更新了我的查询以获取给定比赛中倒数第二个球,然后在百分比计算中进行相应的运行。
【解决方案2】:

要获得倒数第二个球,请使用:

select *
from (
   select matchid, overnum,
          row_number() over (partition by matchid order by overnum desc) as rn
   from bowl
) t
where rn = 2;

您没有提及您正在使用的 DBMS。以上是 ANSI 标准 SQL,几乎所有现代 DBMS 都支持。

【讨论】:

  • 我通过 Java 使用 HSQL(openoffice 基础驱动程序),是否支持?
  • @DuaneAllman:不,HSQLDB 不(还)支持窗口函数。
【解决方案3】:

您需要使用稍微复杂的内部查询。我假设您当然使用的是 SQL Server,尽管 Oracle 实际上可能会让这更容易一些。

select * from Bowl b
where OverNum = 
(
    select top 1 OverNum from 
    (
        select top 2 OverNum 
        from Bowl 
        where Bowl.MatchID = b.MatchID 
        order by OverNum desc
    ) top2 
    order by OverNum asc
)

【讨论】:

    猜你喜欢
    • 2020-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-24
    • 2022-01-08
    • 2019-01-30
    • 2017-07-18
    相关资源
    最近更新 更多