0

統計 (左) とメッセージ (右) の 2 つの MySQL テーブルがあります。

  +------------+---------+      +---------+------------+-----------+----------+
  |  _date     | msgcount|      | msg_id  | _date      | time      |  message |
  +------------+---------+      +----------------------+-----------+----------+
  | 2011-01-22 |  2      |      |   1     | 2011-01-22 |  06:23:11 | foo bar  |
  | 2011-01-23 |  4      |      |   2     | 2011-01-22 |  15:17:03 | baz      |
  | 2011-01-24 |  0      |      |   3     | 2011-01-22 |  17:05:45 | foobar   |
  | 2011-01-25 |  1      |      |   4     | 2011-01-22 |  23:58:13 | barbaz   |
  +------------+---------+      |   5     | 2011-01-23 |  00:06:32 | foo foo  |
                                |   6     | 2011-01-23 |  13:45:00 | bar foo  |
                                |   7     | 2011-01-25 |  02:22:34 | baz baz  |
                                +---------+------------+-----------+----------+

stats.msgcount を入力しましたが、実際にはまだ空です。次のクエリ方法を探しています。

  • すべての stats._date のメッセージ数をカウントします (2011-01-25 のゼロ msgcount に注意してください)
  • messages.time は 24 時間形式です。5 時 (17:00:00) 以降のすべてのメッセージは、翌日にカウントされます (2011-01-23 の msg_id 3 と 4 がカウントされることに注意してください)。
  • すべてのカウントを保持するように stats.msgcount を更新します

特に「17時以降は翌日カウント」の部分が気になります。これは (My)SQL で可能ですか?

4

2 に答える 2

3

あなたが使用することができます:

UPDATE stats LEFT JOIN
  ( SELECT date(addtime(_date,time) + interval 7 hour) as corrected_date, 
           count(*) as message_count
    FROM messages
    GROUP BY corrected_date ) mc
ON stats._date = mc.corrected_date
SET stats.msgcount = COALESCE( mc.message_count, 0 )

ただし、このクエリでは、関心のある日付が統計テーブルに既に含まれている必要があります。まだ _date をプライマリ キーまたは一意のキーにしていない場合は、次を使用します。

INSERT IGNORE INTO stats(_date,msgcount)
SELECT date(addtime(_date,time) + interval 7 hour) as corrected_date,
       count(*) as message_count
FROM messages
GROUP BY corrected_date
于 2012-04-07T00:20:08.200 に答える
1

本当に、あなたがしているのは、時間を 7 時間ずらすだけです。このようなものが動作するはずです:

UPDATE stats s
SET count = (SELECT COUNT(msg_id) FROM messages m
             WHERE m._date BETWEEN DATE_SUB(DATE_ADD(s._date, INTERVAL TIME_TO_SEC(m.time) SECOND), INTERVAL 7 HOUR)
                               AND DATE_ADD(DATE_ADD(s._date, INTERVAL TIME_TO_SEC(m.time) SECOND), INTERVAL 17 HOUR));

基本的な考え方は、統計テーブルの各日付を取得し、それを 7 時間調整して、その範囲内で送信されたメッセージを探すというものです。別々の DATE 列と TIME 列の代わりに DATETIME 列を使用した場合、余分な DATE_ADD(..., TIME_TO_SEC) は必要ありません。

日付と時刻を追加するためのより良い方法があるかもしれません.

したがって、統計テーブルに msgcount に 0 を指定して新しい行を挿入し、update コマンドを実行するだけで済みます。数日だけ更新したい場合 (メッセージ数はおそらく 6 日後に変化しないため)、更新時に簡単な where 句が必要です。

UPDATE stats s
SET ...
WHERE s._date BETWEEN '2012-04-03' AND '2012-04-08'
于 2012-04-07T00:21:02.383 に答える