2

我有下面描述的两个表。我需要的是一个单一的查询,它将告诉我在给定的天数内得分没有变化的球员。

CREATE TABLE players (
  pid INT(50),
  name VARCHAR(255),
  updatedAt DATETIME
);

CREATE TABLE pl_scores (
  pid INT(50),
  score INT(255),
  updatedAt DATETIME
);

players表保留了所有玩家的主列表以及其他不变的数据,为简洁起见未在此处显示。该pl_scores表保留分数变化的运行历史记录,以跟踪增长和其他可能发生变化的值。pl_scores每 6 小时为每个玩家插入一条新记录。

我想得到的是pid在一定天数内没有得分变化的球员,但我不确定如何将其分组以获得正确的值。

示例数据集

(只显示每天的最后一个分数,真正需要比较的只是一个)

+------+------+-------+------+---------+---------------------+
| pid  | aid  | score | rank | cityCnt | updatedAt           |
+------+------+-------+------+---------+---------------------+
| 1660 |    0 |   801 | 2111 |       1 | 2012-06-20 22:14:11 |
| 1660 |    0 |   801 | 2250 |       1 | 2012-06-21 22:15:45 |
| 1660 |    0 |   801 | 2387 |       1 | 2012-06-22 22:17:06 |
| 1660 |    0 |   801 | 2547 |       1 | 2012-06-23 22:17:09 |
| 1660 |    0 |   801 | 2702 |       1 | 2012-06-24 22:19:50 |
| 1660 |    0 |   801 | 2836 |       1 | 2012-06-25 22:21:07 |
| 1660 |    0 |   801 | 2956 |       1 | 2012-06-26 21:42:44 |
+------+------+-------+------+---------+---------------------+

编辑

下面找到的答案完美无缺,但现在我想更进一步,并通过在第三张表中找到的硬编码值来限制结果。这是有效的 SQL 语句

SELECT a.pid, c.aid, b.name AS pName, c.name AS aName, a.score FROM pl_scores AS a 
JOIN players AS b ON a.pid = b.pid 
JOIN alliances AS c ON b.aid = c.aid 
WHERE a.updatedAt >= CURRENT_DATE() - INTERVAL 3 DAY GROUP BY a.pid HAVING MIN(a.score) = MAX(a.score);

每个玩家在世界各地都有多个城市。我想限制在给定大陆上找到城市的玩家的结果。例如,我想找到最近 3 天在 大陆 上没有改变分数的所有玩家34。该cities表如下所示:

CREATE TABLE cities (
  cid INT(50),
  pid INT(50),
  name VARCHAR(255),
  cont INT(10),
  updatedAt DATETIME
);
4

5 回答 5

2

我想它可以用这样的东西来完成:

      SELECT plf.pid, 
             COALESCE(plf.score, 0) AS former_score, 
             COALESCE(pll.score, 0) AS latter_score
        FROM pl_scores AS plf
  RIGHT JOIN (
             SELECT pid, score FROM pl_scores 
             WHERE DATE(updatedAt) = DATE(NOW())
             ) as pll
          ON plf.pid = pll.pid
       WHERE DATE(updatedAt) = DATE(DATE_SUB(NOW(), INTERVAL 3 DAY)) 
      HAVING former_score = latter_score
于 2012-06-29T03:44:32.633 回答
1

您可以pid像这样获得分数不变的玩家:

SELECT pid
FROM pl_scores
WHERE updatedAt >= CURRENT_DATE() - INTERVAL n DAY
GROUP BY pid
HAVING MIN(score) = MAX(score)

现在您可以使用这些pids 来获取有关相应玩家的完整(或更多)信息,例如:

SELECT *  /* or you could specify the necessary columns here */
FROM players
WHERE pid IN (  
  SELECT pid
  FROM pl_scores
  WHERE updatedAt >= CURRENT_DATE() - INTERVAL n DAY
  GROUP BY pid
  HAVING MIN(score) = MAX(score)
)
于 2012-06-29T04:38:21.120 回答
1
SELECT a.pid, c.aid, b.name AS pName, c.name AS aName, a.score FROM pl_scores AS a 
JOIN players AS b ON a.pid = b.pid 
JOIN alliances AS c ON b.aid = c.aid 
JOIN cities AS d ON a.pid = d.pid
WHERE 
a.updatedAt >= CURRENT_DATE() - INTERVAL 3 DAY 
AND d.cont = 34
GROUP BY a.pid HAVING MIN(a.score) = MAX(a.score);
于 2012-06-29T07:33:48.427 回答
0

我认为这样的事情会起作用:

SELECT pid, MIN(updatedAt) AS last FROM pl_scores GROUP BY pid, score HAVING last > '2012-06-24'

于 2012-06-29T03:43:59.260 回答
-1

假设您的updatedAt包含何时输入而不是更新时间,使用 3 天作为检查时间:

SELECT pid FROM
    (SELECT * FROM pl_score GROUP BY pid HAVING updatedAt > DATE_SUB(NOW(), INTERVAL 3 DAY) AND COUNT(DISTINCT(score)) = 1) AS y
JOIN pl_score ON y.pid = pl_score.pid;

阅读此页面以了解有关此类问题的更多信息。

我不能保证这会奏效,但请试一试。

于 2012-06-29T03:47:40.337 回答