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

Tôi có thể sử dụng CTE SQL Server để hợp nhất các ngày giao nhau không?

Viết lại hoàn chỉnh:

;WITH new_grp AS (
   SELECT r1.UserId, r1.StartTime
   FROM   @requests r1
   WHERE  NOT EXISTS (
          SELECT *
          FROM   @requests r2
          WHERE  r1.UserId = r2.UserId
          AND    r2.StartTime <  r1.StartTime
          AND    r2.EndTime   >= r1.StartTime)
   GROUP  BY r1.UserId, r1.StartTime -- there can be > 1
   ),r AS (
   SELECT r.RequestId, r.UserId, r.StartTime, r.EndTime
         ,count(*) AS grp -- guaranteed to be 1+
   FROM   @requests r
   JOIN   new_grp n ON n.UserId = r.UserId AND n.StartTime <= r.StartTime
   GROUP  BY r.RequestId, r.UserId, r.StartTime, r.EndTime
   )
SELECT min(RequestId) AS RequestId
      ,UserId
      ,min(StartTime) AS StartTime
      ,max(EndTime)   AS EndTime
FROM   r
GROUP  BY UserId, grp
ORDER  BY UserId, grp

Bây giờ tạo ra kết quả được yêu cầu và thực sự bao gồm tất cả các trường hợp có thể xảy ra, bao gồm các nhóm phụ không còn tồn tại và các nhóm trùng lặp. Hãy xem nhận xét về dữ liệu thử nghiệm trong bản trình diễn làm việc tại data.SE .

  • CTE 1
    Tìm các điểm (duy nhất!) Trong thời gian bắt đầu một nhóm các khoảng trùng lặp mới.

  • CTE 2
    Đếm số lần bắt đầu nhóm mới lên đến (và bao gồm) mọi khoảng thời gian riêng lẻ, do đó tạo thành một số nhóm duy nhất cho mỗi người dùng.

  • CHỌN CHỌN cuối cùng
    Hợp nhất các nhóm, bắt đầu tai nghe và kết thúc mới nhất cho các nhóm.

Tôi gặp một số khó khăn vì cửa sổ T-SQL hàm max() hoặc sum() không chấp nhận ORDER BY mệnh đề trong một trong một cửa sổ. Họ chỉ có thể tính một giá trị cho mỗi phân vùng, điều này khiến cho không thể tính tổng / số đang chạy trên mỗi phân vùng. Sẽ hoạt động trong PostgreSQL hoặc Oracle (tất nhiên không phải trong MySQL - nó không có chức năng cửa sổ cũng như CTE).

Giải pháp cuối cùng sử dụng thêm một CTE và sẽ nhanh như nhau.



  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ử dụng chỉ mục trong bảng được tối ưu hóa bộ nhớ máy chủ SQL

  2. SMALLDATETIMEFROMPARTS () Ví dụ trong SQL Server (T-SQL)

  3. Xóa tập lệnh SQL Server 2008

  4. Cách chuyển đổi từ định dạng ngày này sang định dạng ngày khác trong SQL Server bằng CONVERT ()

  5. Cần xóa các bản ghi trùng lặp khỏi bảng bằng cách sử dụng row_number ()