これは、シフトされた自己外部結合を変数と組み合わせて使用して実現できます。このソリューションを参照してください:
SELECT IF(COUNT(1) > 0, 1, 0) AS has_consec
FROM
(
SELECT *
FROM
(
SELECT IF(b.login_date IS NULL, @val:[email protected]+1, @val) AS consec_set
FROM tbl a
CROSS JOIN (SELECT @val:=0) var_init
LEFT JOIN tbl b ON
a.user_id = b.user_id AND
a.login_date = b.login_date + INTERVAL 1 DAY
WHERE a.user_id = 1
) a
GROUP BY a.consec_set
HAVING COUNT(1) >= 30
) a
これにより、1
のいずれかが返されます または0
ユーザーがいつでもに30日以上連続してログインしたかどうかに基づきます 過去に。
このクエリの矢面に立つのは、実際には最初の副選択です。これがどのように機能するかをよりよく理解できるように、詳しく見てみましょう。
次のデータセットの例:
CREATE TABLE tbl (
user_id INT,
login_date DATE
);
INSERT INTO tbl VALUES
(1, '2012-04-01'), (2, '2012-04-02'),
(1, '2012-04-25'), (2, '2012-04-03'),
(1, '2012-05-03'), (2, '2012-04-04'),
(1, '2012-05-04'), (2, '2012-05-04'),
(1, '2012-05-05'), (2, '2012-05-06'),
(1, '2012-05-06'), (2, '2012-05-08'),
(1, '2012-05-07'), (2, '2012-05-09'),
(1, '2012-05-09'), (2, '2012-05-11'),
(1, '2012-05-10'), (2, '2012-05-17'),
(1, '2012-05-11'), (2, '2012-05-18'),
(1, '2012-05-12'), (2, '2012-05-19'),
(1, '2012-05-16'), (2, '2012-05-20'),
(1, '2012-05-19'), (2, '2012-05-21'),
(1, '2012-05-20'), (2, '2012-05-22'),
(1, '2012-05-21'), (2, '2012-05-25'),
(1, '2012-05-22'), (2, '2012-05-26'),
(1, '2012-05-25'), (2, '2012-05-27'),
(2, '2012-05-28'),
(2, '2012-05-29'),
(2, '2012-05-30'),
(2, '2012-05-31'),
(2, '2012-06-01'),
(2, '2012-06-02');
このクエリ:
SELECT a.*, b.*, IF(b.login_date IS NULL, @val:[email protected]+1, @val) AS consec_set
FROM tbl a
CROSS JOIN (SELECT @val:=0) var_init
LEFT JOIN tbl b ON
a.user_id = b.user_id AND
a.login_date = b.login_date + INTERVAL 1 DAY
WHERE a.user_id = 1
生成されます:
ご覧のとおり、私たちが行っているのはシフトです。 +1日までに参加したテーブル。前日と連続していない日ごとに、NULL
値はLEFTJOINによって生成されます。
わかった 連続していない日がある場合は、変数を使用して各セットを区別できます。 シフトされたテーブルの行がNULL
であるかどうかを検出することにより、連続する日の数 。 NULL
の場合 、日は連続していないため、変数をインクリメントするだけです。 NOT NULL
の場合 、次に変数をインクリメントしないでください:
増分変数を使用して連続する日の各セットを区別した後は、(consec_set
で定義されているように)各「セット」ごとにグループ化するだけです。 列)およびHAVING
を使用します 指定された連続日数(この例では30日)未満のセットを除外するには:
そして最後に、それをラップします クエリを実行し、30日以上連続したセットの数を単純にカウントします。これらのセットが1つ以上あった場合は、1
を返します。 、それ以外の場合は0
を返します 。