4

次のスキーマがあります。

テーブルの投票

+------------------+--------------+------+-----+---------------------+----------------+
| Field            | Type         | Null | Key | Default             | Extra          |
+------------------+--------------+------+-----+---------------------+----------------+
| id               | int(10)      | NO   | PRI | NULL                | auto_increment |
| aid              | varchar(10)  | NO   |     |                     |                |
| ip               | varchar(100) | NO   |     |                     |                |
| host             | varchar(200) | NO   |     |                     |                |
| timestamp        | varchar(20)  | NO   |     | 0000-00-00 00:00:00 |                |
| user             | tinytext     | NO   |     | NULL                |                |
| userid           | int(10)      | NO   |     | 0                   |                |
+------------------+--------------+------+-----+---------------------+----------------+

ここでは、過去 7 日間の 1 日の各援助の数を取得したいと考えています。援助に対する投票がなかった日付は「0」です。タイムスタンプは、ここでは UNIX タイムスタンプです。

どんな助けでも大歓迎です。

4

2 に答える 2

9

MySQLには再帰機能がないため、NUMBERSテーブルのトリックを使用する必要があります-

  1. 増分数のみを保持するテーブルを作成します-auto_incrementを使用して簡単に実行できます。

    DROP TABLE IF EXISTS `example`.`numbers`;
    CREATE TABLE  `example`.`numbers` (
      `id` int(10) unsigned NOT NULL auto_increment,
       PRIMARY KEY  (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
    
  2. 以下を使用してテーブルにデータを入力します。

    INSERT INTO NUMBERS
      (id)
    VALUES
      (NULL)
    

    ...必要な数の値に対して。

  3. DATE_ADDを使用して日付のリストを作成し、NUMBERS.id値に基づいて日数を増やします。「2010-01-01」と「2010-01-02」をそれぞれの開始日と終了日に置き換えます(ただし、同じ形式YYYY-MM-DD HH:MM:SSを使用します)。この例では、CURRENT_DATEからNUMBERS.id値を減算して、先週の連続した日付値のリストを取得しました-

    SELECT x.dt
      FROM (SELECT DATE_SUB(CURRENT_DATE, INTERVAL (n.id - 1) DAY) AS dt
              FROM numbers n
             WHERE n.id <= 7 ) x
    
  4. 日時部分に基づいてデータのテーブルにLEFTJOINします。

       SELECT x.dt,
               COUNT(v.aid) AS num
         FROM (SELECT DATE_SUB(CURRENT_DATE, INTERVAL (n.id - 1) DAY) AS dt
                 FROM numbers n
                WHERE n.id <= 7 ) x
    LEFT JOIN VOTES v ON DATE(FROM_UNIXTIME(v.timestamp)) = DATE(x.dt)
     GROUP BY x.dt
     ORDER BY x.dt
    

なぜ日付ではなく数字なのか?

単純-私が提供した例のように、日付は数値に基づいて生成できます。また、データ型ごとに1つと言うのではなく、単一のテーブルを使用することも意味します。

以前:

  SELECT DATE(FROM_UNIXTIME(v.timestamp)) AS dt,
         COUNT(v.aid)
    FROM VOTES v
   WHERE DATE(FROM_UNIXTIME(v.timestamp)) BETWEEN DATE_SUB(CURRENT_DATE, INTERVAL 7 DAY)
                                              AND CURRENT_DATE
GROUP BY DATE(FROM_UNIXTIME(v.timestamp))
于 2010-10-17T17:43:59.267 に答える
0

とにかく使用しているので、varchar(20) を DATETIME に変換してみてください。ただし、過去 7 日間については、WHERE タイムスタンプ > @7DaysAgo を実行するだけです。あなたの説明では、UNIX タイムスタンプを使用していると述べたので、今から 7 日後にタイムスタンプを送信する必要があります。DATETIME 値ではなく、タイムスタンプを送信したため、デフォルトを 0 に変更することもできます。

SELECT COUNT(*) を投票として、援助 FROM テーブル WHERE タイムスタンプ>@7DaysAgo GROUP BY 援助

于 2010-10-17T16:54:53.587 に答える