Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

Điều này có thể với mysql không?

Cập nhật khác: Tình cờ (bằng cách sao chép và dán) có starttime = ... or starttime = ... nhưng nó phải là starttime = ... or endtime = ...

CẬP NHẬT:

Để giải thích truy vấn của tôi chi tiết hơn (trong truy vấn cuối cùng, thậm chí còn có nhiều nhận xét hơn):

Đầu tiên, chúng tôi chỉ đơn giản có

SELECT
...
FROM gc_sessions s
WHERE DATE(starttime) = CURDATE() OR DATE(endtime) = CURDATE()

Điều đó không gì giống như nói "cung cấp cho tôi tất cả người dùng có phiên bắt đầu hôm nay hoặc kết thúc hôm nay". Việc phải xem xét lại hai lần như vậy khiến truy vấn hơi vụng về, nhưng thực ra nó không phức tạp như vậy.

Vì vậy, thông thường chúng ta sẽ sử dụng hàm COUNT () để đếm thứ gì đó, nhưng vì chúng ta muốn "đếm có điều kiện", chúng ta chỉ cần sử dụng hàm SUM () và cho biết khi nào thì thêm 1 và khi nào thì không.

SUM (CASE WHEN ... THEN 1 ELSE 0 END) AS a_column_name

Hàm SUM () ngay bây giờ sẽ kiểm tra từng hàng trong tập hợp kết quả của các phiên kể từ hôm nay. Vì vậy, đối với mỗi người dùng trong tập kết quả này, chúng tôi xem xét liệu người dùng này có trực tuyến vào ngày mà chúng tôi chỉ định hay không. Không quan trọng số lần anh ấy / cô ấy trực tuyến, vì vậy vì lý do hiệu suất, chúng tôi sử dụng EXISTS . Với EXISTS bạn có thể chỉ định một truy vấn con dừng ngay khi tìm thấy thứ gì đó, vì vậy nó không quan trọng gì khi tìm thấy thứ gì đó, miễn là nó không phải là NULL . Vì vậy, đừng nhầm lẫn tại sao tôi lại chọn 1 . Trong truy vấn con, chúng ta phải kết nối người dùng hiện đang được kiểm tra từ truy vấn bên ngoài với người dùng từ truy vấn bên trong (truy vấn con) và chỉ định cửa sổ thời gian. Nếu tất cả các tiêu chí đều đáp ứng thì đếm 1 khác 0 như đã giải thích trước đây.

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,

Sau đó, chúng tôi tạo một cột cho mỗi điều kiện và thì đấy, bạn có tất cả những gì bạn cần trong một truy vấn. Vì vậy, với câu hỏi cập nhật của bạn, tiêu chí của bạn đã thay đổi, chúng tôi chỉ cần thêm các quy tắc khác:

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

Vì vậy, tôi hy vọng bạn có được ý tưởng ngay bây giờ. Còn câu hỏi nào nữa không? Mạnh dạn hỏi.

kết thúc cập nhật

Câu trả lời cho phiên bản trước của câu hỏi:

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. Sự cố Mysql khi tạo người dùng mới

  2. Entity Framework + MySQL - Tại sao hiệu suất quá khủng khiếp?

  3. Lỗi mã hóa Unicode Bộ giải mã 'latin-1' không thể mã hóa ký tự '\ u2019'

  4. Cách chèn giá trị vào cột nhận dạng tự động trong MYSQL

  5. Sự cố khởi động máy chủ MySQL trên Mavericks