0

我花了很多很多时间试图弄清楚这一点。所以我的查询在不同的mysql版本上给出了不同的结果。导致我的问题。到目前为止,我发现自 MySQL 5.6 以来,子查询中的 order by 无法识别。这似乎是 5.7 中错误结果的原因。

我想我应该以某种不同的方式从“并且存在”开始整个结束,但我不知道如何。

我已经在 3 台不同的服务器上使用相同的数据库对此进行了测试。一个 5.5(有效),两个 5.7(无效)。

我的查询:有效:5.5,无效:5.6(?),5.7

SELECT
Sum(P) as games 
FROM(SELECT gameday, league, home, season, id, 1 P
FROM games
UNION ALL
SELECT gameday, league, away, season, id, 1
FROM games) as tot, clubs c WHERE tot.home=c.id AND c.id=1 AND
tot.league<=2 AND tot.season=2010 
AND EXISTS
(select if(e.event<10,1,0) as first from 
(select * from events 
where event<=2 or event=9 or event=10 or event=11 or event=13 
order by event_time asc) as e 
where e.game=tot.id group by e.game having first>0)

有任何想法吗?谢谢你。

编辑:

事件可以是 1,2,9,10,11 或 13

我想计算第一个事件<10的游戏。游戏的第一个事件由 event_time 决定。

这有道理吗?

编辑2:

事件表中的列

- id (primary, auto_increment)
- game
- player
- event
- event_time
4

2 回答 2

0

您的第一个目标是从每场比赛中找到第一个符合条件的赛事。“合格”意味着具有event您提到的价值观之一。这里有一个很好的技巧。每场比赛编号最低的id赛事为第一个赛事。

所以这会让你得到这个。这是第一个合格事件的 ids/游戏列表。

             SELECT MIN(id) id, game
               FROM events
              WHERE event < 2
                 OR event IN (9,10,11,13)
              GROUP BY game

接下来,您需要每个游戏的实际第一个事件,而不仅仅是它的 id。

      SELECT a.event, a.game
        FROM event a
        JOIN (
               SELECT MIN(id) id, game
                 FROM events
                GROUP BY game
             ) b ON a.id = b.id
       WHERE a.event < 10

这会产生每个游戏的第一个事件的事件/游戏列表,但它不包括第一个事件值 >= 10 的游戏。

接下来,您正确地提出了主客场比赛的联盟列表。此查询为每个游戏生成一行

       SELECT tot.p
         FROM (
               SELECT gameday, league, home, season, id, 1 AS p FROM games
                UNION ALL
               SELECT gameday, league, away, season, id, 1 AS p FROM games
              ) tot
         JOIN clubs c ON tot.home = c.id
        WHERE tot.league <= 2
          AND tot.season >= 2010
          AND c.id = 1

最后,加入您选择的第一个事件 < 10 的游戏,并将结果相加。

SELECT SUM(tot.p) gamecount
  FROM (
        SELECT gameday, league, home, season, id, 1 AS p FROM games
         UNION ALL
        SELECT gameday, league, away, season, id, 1 AS p FROM games
       ) tot
  JOIN clubs c ON tot.home = c.id
  JOIN (
          SELECT a.event, a.game
            FROM event a
            JOIN (
                   SELECT MIN(id) id, game
                     FROM events
                    GROUP BY game
                 ) b ON a.id = b.id
           WHERE a.event < 10
       ) eligible ON eligible.game = tot.id
 WHERE tot.league <= 2
   AND tot.season >= 2010
   AND c.id = 1

我写这篇文章的目的是在 SQL 中显示“S”——结构化的。从简单的构建块开始构建查询可以获得两件事。

  1. 一个正确的答案
  2. 一种通过运行子查询进行调试的方法,确保它们正常工作,然后将它们合并到更大的查询中。
于 2016-03-11T00:01:22.507 回答
0

最终得到它自己的工作。这是我现在使用的

SELECT
Sum(P) as games 
FROM(SELECT gameday, league, home, season, id, 1 P 
FROM games
UNION ALL
SELECT gameday, league, away, season, id, 1
FROM games) as tot, clubs c WHERE tot.home=c.id AND c.id=1 AND
tot.league<=2 AND tot.season=2010 
AND EXISTS
(select if(e.event<10,1,0) as first from 
(select game, min(event_time), 
substring_index(group_concat(event order by event_time), ',', 1) as event 
from events 
where event<=2 or event=9 or event=10 or event=11 or event=13 
group by game) as e 
where e.game=tot.id having first>0)
于 2016-03-10T16:01:58.640 回答