基本的に、私が試みている結果は、「過去の一定時間内に失敗したレコードが0件の成功したレコードの数を取得する」ことです。「成功」と「失敗」は、列の値を参照するだけです。
もう少し複雑ですが、私が扱っているテーブルの説明は次のとおりです。
`log`
id int PRIMARY KEY AUTO_INCREMENT
fingerprint_id int (foreign key)
status boolean
date timestamp
私たちが持っている小さなシステムのワークフローは、ユーザーが自分の指紋をスワイプすると、このテーブルにレコードが追加され、status
一致したかどうかに基づいて設定されます (さらに、単純化しようとしているだけです)。fingerprint_id
これを行うユーザーに基づいてを取得します。これは、レコードを個人に関連付けるための識別子です。
現時点では、最大 3 回試行する必要があります。したがって、それらは 3 の 1 番目、3 の 2 番目、3 の 3 番目、またはまったく一致しない可能性があります。つまり、「グループ」に 1 つ、2 つ、または 3 つのレコードを含めることができます。真実ではありませんが、ユーザーは 3 回の試行に一致するか、失敗するまで試行を続けると想定できます (1 回か 2 回失敗すると続行しない場合があることがわかりました)。
いくつかのデータの例を次に示します。
id fp_id status date
----------------------------------------
20 2 0 '2013-01-21 12:30:01'
21 2 0 '2013-01-21 12:30:05'
22 2 0 '2013-01-21 12:30:10'
23 9 1 '2013-01-21 12:31:30'
24 1 0 '2013-01-21 12:35:00'
25 1 1 '2013-01-21 12:35:05'
データでは、ユーザー ( fingerprint_id
) 2 は 3 回試行しましたが、一致しませんでした。ユーザー 9 は、最初の試行で一致しました。ユーザー 1 は 1 回試行して失敗し、再度試行して一致しました。
ポイントは、 35 秒前に成功した ( status
=1) ログ レコードのうち、失敗した ( =0) レコードが 0 件あるログ レコードの数を調べることです。status
もちろん、それらを「接続」する唯一の方法はfingerprint_id
.
繰り返しますが、多くのことを想定していますが、それで問題ありません。
これが私の試みです:
SELECT COUNT(*)
FROM log AS log_main
WHERE log_main.status=1 AND
(SELECT COUNT(*)
FROM log AS log_inner
WHERE log_inner.fingerprint_id=log_main.fingerprint_id AND
log_inner.status=0 AND
log_inner.date<log_main.date AND log_inner.date>=(log_main.date - INTERVAL 35 SECOND))=0
^ これは、35 秒以内に (そのユーザーに対して) 発生した失敗したレコードの数が 0 であるすべての成功したレコードを選択することを期待しています。しかし、クエリには 600 秒以上かかるため、わかりません。MySQL Workbench の最大タイムアウトを延長する方法を見つけたところですが、いずれにしても非常に時間がかかります。テーブルには合計で約 120,000 のレコードがあるため、このクエリがそれほど遅くなるのに十分かどうかはわかりません。
とにかく、ここに別の試みがあります:
SELECT COUNT(*)
FROM (SELECT log.fingerprint_id, log.date
FROM log
WHERE log.status=1) successful,
(SELECT log.fingerprint_id, log.date
FROM log
WHERE log.status=0) unsuccessful
WHERE successful.fingerprint_id=unsuccessful.fingerprint_id AND
unsuccessful.date<successful.date AND unsuccessful.date>=(successful.date - INTERVAL 35 SECOND)
^ こっちの方が近いような気もするが、もちろん過去に何件のレコードが一致したかという「カウント」での比較はない。それは私が解決方法について混乱している部分です。と関係があるGROUP BY
か、代わりに を使用しているように感じますIN
が、私が行ったことはうまくいかないようです (600 秒を超えるなどの意味で)。これは私が試したものの例ですGROUP BY
SELECT successful.id, COUNT(*) cnt
FROM (SELECT log.fingerprint_id, log.date, log.id
FROM log
WHERE log.status=1) successful,
(SELECT log.fingerprint_id, log.date, log.id
FROM log
WHERE log.status=0) unsuccessful
WHERE successful.fingerprint_id=unsuccessful.fingerprint_id AND
unsuccessful.date<successful.date AND unsuccessful.date>=(successful.date - INTERVAL 35 SECOND)
GROUP BY successful.id
^ ただし、結果には NOT 0 カウントを持つ行のみが含まれます。WHERE
そして、それは条項のせいだと思います。しかし、私は0カウントだけが必要です。
私は非常に多くの組み合わせを試しましたが、私の脳はただ揚げられていると思います.