2

以下に説明する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_scores6 時間ごとに各プレイヤーの新しいレコードが挿入されます。

私が取得したいのは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);

各プレイヤーは、世界中に複数の都市を持っています。特定の大陸で見つかった都市を持つプレーヤーによる結果を制限したいと思います。たとえば、 continent で過去 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
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 に答える
1

pid次のように、スコアが変更されていない s 人のプレーヤーを取得できます。

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)
)
于 2012-06-29T04:38:21.120 に答える
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 に答える