web-dev-qa-db-ja.com

IN句を使用して異なる日付の行を取得する方法

私のテーブル構造:

+-----------------+--------------+------+-----+-------------------+----------------+
| Field           | Type         | Null | Key | Default           | Extra          |
+-----------------+--------------+------+-----+-------------------+----------------+
| id              | int(11)      | NO   | PRI | NULL              | auto_increment |
| user            | varchar(100) | NO   |     | NULL              |                |
| uniq_name       | varchar(100) | NO   |     | NULL              |                |
| info_name       | varchar(100) | NO   |     | NULL              |                |
| delay_time      | int(11)      | NO   |     | NULL              |                |
| track_time      | timestamp    | NO   |     | CURRENT_TIMESTAMP |                |
+-----------------+--------------+------+-----+-------------------+----------------+

合計1日ではなく、過去7日間データをテーブルから取得する必要があります。特定の日付のデータ。このため、今のところ、like演算子を使用して同じクエリを7回実行する必要があります。

SELECT COUNT(DISTINCT `user`) FROM `tracks` WHERE `track_time` LIKE '2012-11-12%';

これは良い方法ではありません。私も自分でやろうとしています。フォーラムでも議論されています。これは[〜#〜] in [〜#〜]演算子を使用するか、過去1日間にdate1 <date2 <.... date日々。このため、PHPで関数を使用しています。ここで日付パラメーターを指定していますが、クエリがWebに結果を表示するのに時間がかかります。この状況を確認してください。

4
Shashank

連続する日付の範囲を実行している場合は、IN演算子を使用する必要はありません。

これを使用して7日前の真夜中を計算する場合

_DATE(NOW()) - INTERVAL 7 DAY + INTERVAL 0 SECOND
_

ここにあなたが取り戻すものがあります:

_mysql> SELECT DATE(NOW()) - INTERVAL 7 DAY + INTERVAL 0 SECOND;
+--------------------------------------------------+
| DATE(NOW()) - INTERVAL 7 DAY + INTERVAL 0 SECOND |
+--------------------------------------------------+
| 2012-11-21 00:00:00                              |
+--------------------------------------------------+
1 row in set (0.01 sec)

mysql>
_

クエリは次のようになります。

_SELECT COUNT(DISTINCT `user`) FROM `tracks`
WHERE `track_time` >= ( DATE(NOW()) - INTERVAL 7 DAY + INTERVAL 0 SECOND );
_

WHEREおよびCOUNTをサポートするためのインデックスも必要です。

_ALTER TABLE tracks ADD INDEX track_time_user_ndx (track_time,user);
_

その後、クエリはより高速になります。

以前の期間から連続した日付の範囲を実行する場合は、真夜中から真夜中までの最初と最後の日付を指定するだけです。たとえば、_2012-11-12_から_2012-11-19_の範囲の場合:

_SELECT COUNT(DISTINCT `user`) FROM `tracks`
WHERE `track_time` >= '2012-11-12 00:00:00'
AND   `track_time` <  '2012-11-19 00:00:00';
_

連続しない日付の範囲を実行している場合は、UNIONを使用してクエリを構造化するだけです。たとえば、日付_2012-11-12_、_2012-11-19_、_2012-11-26_の場合:

_SELECT COUNT(DISTINCT `user`) FROM
(
    SELECT user,track_time FROM `tracks`
    WHERE `track_time` >= '2012-11-12 00:00:00'
    AND   `track_time` <= '2012-11-12 23:59:59'
    UNION
    SELECT user,track_time FROM `tracks`
    WHERE `track_time` >= '2012-11-19 00:00:00'
    AND   `track_time` <= '2012-11-19 23:59:59'
    UNION
    SELECT user,track_time FROM `tracks`
    WHERE `track_time` >= '2012-11-26 00:00:00'
    AND   `track_time` <= '2012-11-26 23:59:59'
) A;
_

試してみる !!!

更新2012-11-27 13:52

1つの日付だけの個別のユーザーの数が必要な場合_2012-11-12_

_SELECT COUNT(DISTINCT user) usercount FROM `tracks`
WHERE `track_time` >= '2012-11-12 00:00:00'
AND   `track_time` <= '2012-11-12 23:59:59';
_

7つの連続した日付の異なるユーザーの数が必要な場合_2012-11-12_-_2012-11-18_(_2012-11-19_を含めることはできません)

_SELECT
    DATE(track_time) track_date,
    COUNT(DISTINCT user) usercount
FROM
(
    SELECT user,track_time FROM `tracks`
    WHERE `track_time` >= '2012-11-12 00:00:00'
    AND   `track_time` <  '2012-11-19 00:00:00'
) A GROUP BY DATE(track_time);
_

更新2012-11-27 14:41 EDT

これをNOW()の時点で動的に実行したい場合は、これを試してください:

_SELECT
    DATE(track_time) track_date,
    COUNT(DISTINCT user) usercount
FROM
(
    SELECT user,track_time FROM `tracks`
    WHERE `track_time` >= ( DATE(NOW()) - INTERVAL 7 DAY + INTERVAL 0 SECOND )
) A GROUP BY DATE(track_time);
_
6
RolandoMySQLDBA