1

現在、次のクエリを使用して、日ごとにグループ化されたデータを取得しています。

SELECT DATE(from_unixtime(timestampcolumn)) as date, COUNT(*)
FROM db.table
WHERE timestampcolumn BETWEEN :startTime AND :endTime
GROUP BY DATE(from_unixtime(timestampcolumn))
ORDER BY timestampcolumn

DATE()関数は string を返すためYYYY-MM-DD、上記のクエリは単純で、日ごとにグループ化されたデータを取得するのに最適ですが、週ごとにグループ化されたデータを返すように変更するにはどうすればよいですか?


ジョナサンの答えに応えて:

SQL Fiddle で例を作成しようとしましたが、DATE()何らかの理由で SQL 関数が SQL Fiddle で機能しません (単に SQL Fiddle では機能しませんが、ライブ サーバーと wamp サーバーの両方で機能します)。

そのため、必要に応じて試すことができる例を次に示します。

設定:

CREATE TABLE example(id INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(id), timestamp INT, data INT);

INSERT INTO example (timestamp, data) VALUES (1355400000, 1);
INSERT INTO example (timestamp, data) VALUES (1355659200, 1);
INSERT INTO example (timestamp, data) VALUES (1357694861, 1);
INSERT INTO example (timestamp, data) VALUES (1355918400, 1);
INSERT INTO example (timestamp, data) VALUES (1356955200, 1);
INSERT INTO example (timestamp, data) VALUES (1358510400, 1);
INSERT INTO example (timestamp, data) VALUES (1358769600, 1);
INSERT INTO example (timestamp, data) VALUES (1358769600, 1);
INSERT INTO example (timestamp, data) VALUES (1371824368, 1);
INSERT INTO example (timestamp, data) VALUES (1371833476, 1);
INSERT INTO example (timestamp, data) VALUES (1371840324, 1);
INSERT INTO example (timestamp, data) VALUES (1371850523, 1);
INSERT INTO example (timestamp, data) VALUES (1371863191, 1);
INSERT INTO example (timestamp, data) VALUES (1371865401, 1);
INSERT INTO example (timestamp, data) VALUES (1371872379, 1);
INSERT INTO example (timestamp, data) VALUES (1372006190, 1);
INSERT INTO example (timestamp, data) VALUES (1372051945, 1);
INSERT INTO example (timestamp, data) VALUES (1372189402, 1);
INSERT INTO example (timestamp, data) VALUES (1372207830, 1);
INSERT INTO example (timestamp, data) VALUES (1372229733, 1);
INSERT INTO example (timestamp, data) VALUES (1372350338, 1);
INSERT INTO example (timestamp, data) VALUES (1372358259, 1);

クエリ:

SELECT DATE(from_unixtime(timestamp)) as date, COUNT(*)
FROM example
WHERE timestamp BETWEEN 0 AND 9999999999999999999999999999999
GROUP BY DATE(from_unixtime(timestamp))
ORDER BY timestamp

出力:

2012-12-13  1
2012-12-16  1
2012-12-19  1
2012-12-31  1
2013-01-08  1
2013-01-18  1
2013-01-21  2
2013-06-21  7
2013-06-23  1
2013-06-24  1
2013-06-25  2
2013-06-26  1
2013-06-27  2

ここで、タイムスタンプを で割り(7 * 24 * 3600)ます。

クエリ:

SELECT DATE(from_unixtime(timestamp / (7 * 24 * 3600))) as date, COUNT(*)
FROM example
WHERE timestamp BETWEEN 0 AND 9999999999999999999999999999999
GROUP BY DATE(from_unixtime(timestamp / (7 * 24 * 3600)))
ORDER BY timestamp

出力:

1969-12-31  22
4

3 に答える 3

3

基本的な考え方の 1 つは、タイム スタンプの整数値を 1 週間の秒数で割った値でグループ化することです。timestampcolumn / (7 * 24 * 3600)

次に、エッジ効果とタイム ゾーンを考慮する必要があります。

  • 1970 年 1 月 1 日は適切な曜日でした (木曜日だったので、おそらくそうではありませんでした)。
  • 指定されたデータの週の始まりは正確にはいつですか。冬時間と夏時間 (標準時間と夏時間) の影響はありますか?

分割する前に、タイムスタンプ列に適切な値を追加することで対処できます。最後にひねりを加えます。システムによっては、うるう秒を補正する場合があります。POSIX にはありません。それがあなたにとって重要かどうかを判断する必要があります。

考慮すべきもう 1 つのオプションは、日付を週の値としてフォーマットする方法があるかどうかです (たとえば、2013 年の第 23 週を表す 2013-W23 などの ISO 8601 表記)。その後、その文字列で簡単にグループ化できます。


これは私が意味したものです:

SELECT timestamp / (7 * 24 * 3600) AS weekno, COUNT(*)
  FROM example
 WHERE timestamp BETWEEN 0 AND 9999999999999999999999999999999
 GROUP BY timestamp / (7 * 24 * 3600)
 ORDER BY weekno

を使用できる場合GROUP BY weeknoもあれば、使用する必要がある場合もありますORDER BY timestamp / (7 * 24 * 3600)が、週番号を作成します。日付も生成する必要がある場合は、次を使用します。

SELECT timestamp / (7 * 24 * 3600) AS weekno,
       DATE(FROM_UNIXTIME((7 * 24 * 3600) * INT(timestamp / (7 * 24 * 3600))))) AS weekstart,
       COUNT(*)
  FROM example
 WHERE timestamp BETWEEN 0 AND 9999999999999999999999999999999
 GROUP BY timestamp / (7 * 24 * 3600)
 ORDER BY weekno

週の最初の曜日が常にデータに表示されるとは限らない場合を除き、おそらくMIN(DATE(FROM_UNIXTIME(timestamp)))forも使用できます。weekstart

于 2013-06-27T20:05:55.193 に答える
1

元のクエリを使用して、DAY() の代わりに WEEK 関数を使用することはできませんか?

GROUP BY WEEK(from_unixtime(timestampcolumn))
于 2016-10-12T21:25:42.273 に答える