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

Đếm số lượt truy cập liên tiếp

Tôi đã bỏ lỡ thẻ mysql và đã viết ra giải pháp này. Đáng buồn thay, điều này không hoạt động trong MySQL vì nó không hỗ trợ các chức năng cửa sổ .

Tôi đăng nó bằng mọi cách, vì tôi đã nỗ lực vào nó. Đã thử nghiệm với PostgreSQL. Sẽ hoạt động tương tự với Oracle hoặc SQL Server (hoặc bất kỳ RDBMS phù hợp nào khác hỗ trợ các chức năng cửa sổ).

Thiết lập thử nghiệm

CREATE TEMP TABLE v(id int, visit date);
INSERT INTO v VALUES
 (444631, '2011-11-07')
,(444631, '2011-11-06')
,(444631, '2011-11-05')
,(444631, '2011-11-04')
,(444631, '2011-11-02')
,(444631, '2011-11-01')
,(444632, '2011-12-02')
,(444632, '2011-12-03')
,(444632, '2011-12-05');

Phiên bản đơn giản

-- add 1 to "difference" to get number of days of the longest period
SELECT id, max(dur) + 1 as max_consecutive_days
FROM (

   -- calculate date difference of min and max in the group
   SELECT id, grp, max(visit) - min(visit) as dur
   FROM (

      -- consecutive days end up in a group
      SELECT *, sum(step) OVER (ORDER BY id, rn) AS grp
      FROM   (

         -- step up at the start of a new group of days
         SELECT id
               ,row_number() OVER w AS rn
               ,visit
               ,CASE WHEN COALESCE(visit - lag(visit) OVER w, 1) = 1
                THEN 0 ELSE 1 END AS step
         FROM   v
         WINDOW w AS (PARTITION BY id ORDER BY visit)
         ORDER  BY 1,2
         ) x
      ) y
      GROUP BY 1,2
   ) z
GROUP  BY 1
ORDER  BY 1
LIMIT  1;

Đầu ra:

   id   | max_consecutive_days
--------+----------------------
 444631 |                    4

Nhanh hơn / Ngắn hơn

Sau đó tôi đã tìm thấy một cách thậm chí còn tốt hơn. grp số lượng không liên tục (nhưng liên tục tăng). Không quan trọng, vì đó chỉ là ý nghĩa để kết thúc:

SELECT id, max(dur) + 1 AS max_consecutive_days
FROM (
    SELECT id, grp, max(visit) - min(visit) AS dur
    FROM (
      -- subtract an integer representing the number of day from the row_number()
      -- creates a "group number" (grp) for consecutive days
      SELECT id
            ,EXTRACT(epoch from visit)::int / 86400
           - row_number() OVER (PARTITION BY id ORDER BY visit) AS grp
            ,visit
      FROM   v
      ORDER  BY 1,2
      ) x
    GROUP BY 1,2
    ) y
GROUP  BY 1
ORDER  BY 1
LIMIT  1;

SQL Fiddle cho cả hai.

Thêm



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cách sử dụng trigger trong MySql để tạo khóa ngoại

  2. Cách tạo Trình kích hoạt để thêm các sự kiện thay đổi vào bảng Nhật ký kiểm tra

  3. Xuất và nhập tất cả cơ sở dữ liệu MySQL cùng một lúc

  4. Đếm từ một bảng, nhưng dừng đếm ở một số nhất định

  5. MySQL INSERT INTO trực tiếp với mệnh đề WHERE