それは(あなたはこれをたくさんやろうとしている場合、クエリの読みやすさのためにfunctionsを追加したい場合があります)きれいではありません
あなたが複数日にまたがるログインがまたはpする場合、それは動作しません
SELECT
user_id,
SUM(
TIMESTAMPDIFF(SECOND,
CASE
WHEN sessions.checkin < timestamp(date(sessions.checkin), maketime(9,0,0))
THEN timestamp(date(sessions.checkin), maketime(9,0,0))
WHEN sessions.checkin > timestamp(date(sessions.checkin), maketime(18,0,0))
THEN timestamp(date(sessions.checkin)+1, maketime(9,0,0))
ELSE
sessions.checkin
END,
CASE
WHEN IFNULL(sessions.checkout, now()) > timestamp(date(IFNULL(sessions.checkout, now())), maketime(18,0,0))
THEN timestamp(date(IFNULL(sessions.checkout, now())), maketime(18,0,0))
WHEN IFNULL(sessions.checkout, now()) < timestamp(date(IFNULL(sessions.checkout, now())), maketime(9,0,0))
THEN timestamp(date(IFNULL(sessions.checkout, now()))-1, maketime(18,0,0))
ELSE
IFNULL(sessions.checkout, now())
END)) AS score
FROM `sessions`
GROUP BY `user_id`
次を行うことができます複数日にまたがるログインしていないと仮定すると、 1日目の18時05分にチェックインし、3日目の8時55分にチェックアウトするなど、複数の日にまたがるログインで動作することができますが、複数の日にカウント可能な時間に達するとすぐに、複数の日にカウント可能な時間にまたがるレコードごとに、結果から無制限の秒数を差し引く必要があります。もしあなたがそれに助けが必要なら私に教えてください。
上記のクエリは、比較的安価で実行する必要があります -とにかくあなたがテーブル全体上でそれを実行しているという事実を考えると、それはテーブルスキャンを行います、繰り返し計算が多いという事実と、それが見えること巨大なものはそれほど重要ではありません。これらの計算は追加のI/Oなしでメモリ内で実行され、ディスクI/Oよりも数桁高速です(元のクエリの実行時間と比較して、パフォーマンスが低下するかどうかをお知らせください)。
これは完全にMySQLでなければならないのですか、それともプログラミング言語で行うことはできますか?それは非常に複雑なクエリのように聞こえる。 – Danosaure
もしあなたが好きなのであれば、phpで行うこともできます。 それはうまくいくでしょうか?18:00と09:00の差を計算し、それを掛けた日数を掛けます。 – sparkle