Pembaruan Lain: Tidak sengaja (dengan copy&paste) memiliki starttime = ... or starttime = ...
tapi seharusnya starttime = ... or endtime = ...
PERBARUI:
Untuk menjelaskan pertanyaan saya secara lebih rinci (dalam permintaan terakhir bahkan ada lebih banyak komentar):
Pertama kita hanya mendapatkan
SELECT
...
FROM gc_sessions s
WHERE DATE(starttime) = CURDATE() OR DATE(endtime) = CURDATE()
Itu tidak lebih seperti mengatakan "beri saya semua pengguna yang sesinya dimulai hari ini atau berakhir hari ini". Harus mempertimbangkan dua kali lagi dan lagi membuat kueri agak canggung, tetapi sebenarnya tidak terlalu rumit.
Jadi, biasanya kita akan menggunakan fungsi COUNT() untuk menghitung sesuatu, tentu saja, tetapi karena kita menginginkan "penghitungan bersyarat", kita cukup menggunakan fungsi SUM() dan memberi tahu kapan harus menambahkan 1 dan kapan tidak.
SUM (CASE WHEN ... THEN 1 ELSE 0 END) AS a_column_name
Fungsi SUM() sekarang memeriksa setiap baris dalam kumpulan hasil sesi mulai hari ini. Jadi untuk setiap pengguna dalam kumpulan hasil ini, kami melihat apakah pengguna ini online pada tanggal yang kami tentukan. Tidak masalah berapa kali dia online, jadi untuk alasan kinerja kami menggunakan EXISTS
. Dengan EXISTS
anda dapat menentukan subquery yang berhenti segera setelah sesuatu ditemukan, jadi tidak masalah apa yang dikembalikan ketika sesuatu ditemukan, selama itu bukan NULL
. Jadi jangan bingung kenapa saya memilih 1
. Pada subquery kita harus menghubungkan user yang sedang diperiksa dari outer query dengan user dari inner query (subquery) dan menentukan time window. Jika semua kriteria memenuhi hitung 1 lagi 0 seperti yang dijelaskan sebelumnya.
SUM(CASE WHEN
EXISTS (SELECT 1 FROM gc_sessions sub_s WHERE s.user = sub_s.user
AND ((date(starttime) = CURDATE() - INTERVAL 1 DAY)
OR (date(endtime) = CURDATE() - INTERVAL 1 DAY)))
THEN 1 ELSE 0 END) AS todayAndYesterday,
Kemudian kami membuat kolom untuk setiap kondisi dan voila, Anda memiliki semua yang Anda butuhkan dalam satu kueri. Jadi dengan pertanyaan Anda yang diperbarui, kriteria Anda telah berubah, kami hanya perlu menambahkan lebih banyak aturan:
SELECT
/*this is like before*/
SUM(CASE WHEN
EXISTS (SELECT 1 FROM gc_sessions sub_s WHERE s.user = sub_s.user
AND ((date(starttime) = CURDATE() - INTERVAL 1 DAY)
OR (date(endtime) = CURDATE() - INTERVAL 1 DAY)))
THEN 1 ELSE 0 END) AS FridayAndThursday,
SUM(CASE WHEN
EXISTS (SELECT 1 FROM gc_sessions sub_s WHERE s.user = sub_s.user
AND ((date(starttime) = CURDATE() - INTERVAL 2 DAY)
OR (date(endtime) = CURDATE() - INTERVAL 2 DAY)))
/*this one here is a new addition, since you don't want to count the users that were online yesterday*/
AND NOT EXISTS (SELECT 1 FROM gc_sessions sub_s WHERE s.user = sub_s.user
AND ((date(starttime) = CURDATE() - INTERVAL 1 DAY)
OR (date(endtime) = CURDATE() - INTERVAL 1 DAY)))
THEN 1 ELSE 0 END) AS FridayAndWednesdayButNotThursday,
SUM(CASE WHEN
EXISTS (SELECT 1 FROM gc_sessions sub_s WHERE s.user = sub_s.user
AND ((date(starttime) = CURDATE() - INTERVAL 3 DAY) /* minus 3 days to get tuesday*/
OR (date(endtime) = CURDATE() - INTERVAL 3 DAY)))
/*this is the same as before, we check again that the user was not online between today and tuesday, but this time we really use BETWEEN for convenience*/
AND NOT EXISTS (SELECT 1 FROM gc_sessions sub_s WHERE s.user = sub_s.user
AND ((date(starttime) BETWEEN CURDATE() - INTERVAL 2 DAY AND CURDATE() - INTERVAL 1 DAY)
OR (date(endtime) BETWEEN CURDATE() - INTERVAL 2 DAY AND CURDATE() - INTERVAL 1 DAY)))
THEN 1 ELSE 0 END) AS FridayAndTuesdayButNotThursdayAndNotWednesday,
.../*and so on*/
FROM gc_sessions s
WHERE DATE(starttime) = CURDATE() OR DATE(endtime) = CURDATE()
Jadi, saya harap Anda mendapatkan ide sekarang. Ada pertanyaan lagi? Jangan ragu untuk bertanya.
akhir pembaruan
Jawaban pertanyaan versi sebelumnya:
select
SUM(CASE WHEN EXISTS (SELECT 1 FROM gc_sessions sub_s WHERE s.user = sub_s.user
AND ((date(starttime) = CURDATE() - INTERVAL 1 DAY)
OR (date(starttime) = CURDATE() - INTERVAL 1 DAY)))
THEN 1 ELSE 0 END) AS todayAndYesterday,
SUM(CASE WHEN EXISTS (SELECT 1 FROM gc_sessions sub_s WHERE s.user = sub_s.user
AND ((date(starttime) BETWEEN CURDATE() - INTERVAL 2 DAY AND CURDATE() - INTERVAL 1 DAY)
OR (date(starttime) BETWEEN CURDATE() - INTERVAL 2 DAY AND CURDATE() - INTERVAL 1 DAY)))
THEN 1 ELSE 0 END) AS todayAndYesterdayOrTheDayBeforeYesterday,
SUM(CASE WHEN EXISTS (SELECT 1 FROM gc_sessions sub_s WHERE s.user = sub_s.user
AND ((date(starttime) BETWEEN CURDATE() - INTERVAL 7 DAY AND CURDATE() - INTERVAL 1 DAY)
OR (date(starttime) BETWEEN CURDATE() - INTERVAL 7 DAY AND CURDATE() - INTERVAL 1 DAY)))
THEN 1 ELSE 0 END) AS todayAndWithinTheLastWeek
from gc_sessions s
where date(starttime) = CURDATE()
or date(endtime) = CURDATE()