Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

Apakah ini mungkin dengan mysql?

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()


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Merancang database :Pendekatan mana yang lebih baik?

  2. Bagaimana cara menambahkan lebih dari satu baris dengan Zend_Db?

  3. Cara mengimpor dump MySQL dari baris perintah DENGAN menimpa

  4. Kesalahan penguraian:kesalahan sintaksis, 'mysql_query' (T_STRING) tak terduga di

  5. Apa cara tercepat untuk polling tabel MySQL untuk baris baru?