我有两个表格如下所述。我需要的是一个单一的查询,它会告诉我在给定天数内得分没有变化的球员。
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
表保留了分数变化的运行历史记录,以跟踪可能发生变化的增长和其他值。每6小时为每位玩家添加一条新记录pl_scores
。
我想得到的是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 |
+------+------+-------+------+---------+---------------------+
修改
下面找到的答案工作得很好,但现在我想更进一步,并通过第3个表中的硬编码值限制结果。这是工作的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);
每个玩家在世界各地都有多个城市。我想限制在特定大陆上找到的城市玩家的结果。例如,我想找到在大陆34
过去3天内未改变分数的每位球员。 cities
表如下所示:
CREATE TABLE cities (
cid INT(50),
pid INT(50),
name VARCHAR(255),
cont INT(10),
updatedAt DATETIME
);
答案 0 :(得分: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
答案 1 :(得分:1)
你可以让pid
个玩家的得分保持不变:
SELECT pid
FROM pl_scores
WHERE updatedAt >= CURRENT_DATE() - INTERVAL n DAY
GROUP BY pid
HAVING MIN(score) = MAX(score)
现在您可以使用这些pid
来获取有关相应玩家的完整(或更多)信息,例如:
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)
)
答案 2 :(得分: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);
答案 3 :(得分:0)
我觉得这样的事情会奏效:
SELECT pid, MIN(updatedAt) AS last FROM pl_scores GROUP BY pid, score HAVING last > '2012-06-24'
答案 4 :(得分:-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;
阅读this page以了解有关此类问题的更多信息。
我不能保证这会起作用,但试一试。