訪問データの表があります。
uid (INT) | created_at (DATETIME)
ユーザーがアプリに何日続けてアクセスしたかを知りたい。たとえば、次のようになります。
SELECT DISTINCT DATE(created_at) AS d FROM visits WHERE uid = 123
戻ります:
d
------------
2012-04-28
2012-04-29
2012-04-30
2012-05-03
2012-05-04
5つのレコードと2つの間隔があります-3日(4月28日から30日)と2日(5月3日から4日)。
私の質問は、ユーザーがアプリに連続してアクセスした最大日数(例では3日)を見つける方法です。SQLドキュメントで適切な関数を見つけようとしましたが、成功しませんでした。私は何かが足りないのですか?
UPD: 皆さん、答えてくれてありがとう!実際、私はvertica分析データベース(http://vertica.com/)を使用していますが、これは非常にまれなソリューションであり、経験のある人はごくわずかです。SQL-99標準をサポートしていますが。
さて、ほとんどのソリューションはわずかな変更で機能します。最後に、独自のバージョンのクエリを作成しました。
-- returns starts of the vitit series
SELECT t1.d as s FROM testing t1
LEFT JOIN testing t2 ON DATE(t2.d) = DATE(TIMESTAMPADD('day', -1, t1.d))
WHERE t2.d is null GROUP BY t1.d
s
---------------------
2012-04-28 01:00:00
2012-05-03 01:00:00
-- returns end of the vitit series
SELECT t1.d as f FROM testing t1
LEFT JOIN testing t2 ON DATE(t2.d) = DATE(TIMESTAMPADD('day', 1, t1.d))
WHERE t2.d is null GROUP BY t1.d
f
---------------------
2012-04-30 01:00:00
2012-05-04 01:00:00
したがって、今必要なのは、たとえば行インデックスなど、何らかの方法でそれらを結合することだけです。
SELECT s, f, DATEDIFF(day, s, f) + 1 as seq FROM (
SELECT t1.d as s, ROW_NUMBER() OVER () as o1 FROM testing t1
LEFT JOIN testing t2 ON DATE(t2.d) = DATE(TIMESTAMPADD('day', -1, t1.d))
WHERE t2.d is null GROUP BY t1.d
) tbl1 LEFT JOIN (
SELECT t1.d as f, ROW_NUMBER() OVER () as o2 FROM testing t1
LEFT JOIN testing t2 ON DATE(t2.d) = DATE(TIMESTAMPADD('day', 1, t1.d))
WHERE t2.d is null GROUP BY t1.d
) tbl2 ON o1 = o2
サンプル出力:
s | f | seq
---------------------+---------------------+-----
2012-04-28 01:00:00 | 2012-04-30 01:00:00 | 3
2012-05-03 01:00:00 | 2012-05-04 01:00:00 | 2