基本上相關記錄的記錄,我試圖結局是:「獲得成功記錄有一定的時間到過去在0 不成功記錄數」。 「成功」和「不成功」只是指一列的價值。查找在過去
雖然這是一個有點複雜,這裏的表我處理的描述:
`log`
id int PRIMARY KEY AUTO_INCREMENT
fingerprint_id int (foreign key)
status boolean
date timestamp
我們的小系統的工作流程是,當用戶掃描他們的指紋,記錄是添加到此表並status
基於它是否匹配(再次,還有更多,我只是想簡化)。我們得到fingerprint_id
的基礎是用戶這樣做,所以這是相關記錄給一個人的標識符。
現在,我們要求他們最多嘗試3次。所以,他們可以在3日的第一場比賽中,3場比賽中的第2場比賽,或3場比賽中的第3場比賽,或者根本沒有比賽。這意味着他們可以在他們的「組」中有1,2或3條記錄。雖然這不是事實,但我們可以假設用戶會繼續嘗試,直到他們匹配或達到3次失敗的嘗試(我們發現有時人們在失敗一次或兩次後可能不會繼續)。
這裏的一些數據的一個例子:
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嘗試過一次失敗,然後再次嘗試匹配。
問題的關鍵是要在35秒內找出有多少次成功(status
= 1)日誌記錄有0次失敗(status
= 0)記錄。當然,「連接」它們的唯一方法是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
試過^但結果只包含那些沒有0計數行的一些例子。我猜這是因爲WHERE
條款。但我只需要0計數。
我試過這麼多的組合,我想我的大腦只是被炸。
一點:關於運行這麼長時間的查詢,你有索引,你需要這些查詢有機會執行好嗎? – DWright
@DWright我有一種感覺可能是一個問題。不幸的是,我們沒有。巧合的是,我是在不久前加入團隊的時候決定開始清理數據庫的人,並且已經有查詢準備添加INDEX。問題是我正在生產服務器上測試這些查詢(數據真的很重要),並且寧願等到今晚有些停機時間才能修改表。對我來說,INDEXes在'fingerprint_id'和'date'列上有意義。這可能是對的嗎? – Ian