Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Мога ли да използвам CTE на SQL Server за обединяване на пресичащи се дати?

Пълно пренаписване:

;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

Сега произвежда искания резултат инаистина покрива всички възможни случаи, включително отделни подгрупи и дубликати. Разгледайте коментарите към тестовите данни в работна демонстрация в data.SE .

  • CTE 1
    Намерете (уникалните!) точки във времето, където започва нова група от припокриващи се интервали.

  • CTE 2
    Преброява стартиранията на нова група до (и включително) всеки отделен интервал, като по този начин формира уникален номер на група за потребител.

  • Краен ИЗБОР
    Обединете групите, вземете по-ранен старт и най-късен край за групите.

Сблъсках се с известна трудност, тъй като прозоречните функции на T-SQL max() или sum() не приемайте ORDER BY клауза в a в прозорец. Те могат да изчислят само една стойност на дял, което прави невъзможно изчисляването на текуща сума/брой на дял. Ще работи в PostgreSQL или Oracle (но не и в MySQL, разбира се - няма нито функции за прозорец, нито CTE).

Крайното решение използва един допълнителен CTE и трябва да бъде също толкова бързо.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Променете разделителя на запетая, когато изпращате по имейл резултати от заявка в SQL Server (T-SQL)

  2. Нови функции в SQL Server 2017 (Database Engine)

  3. Не използвайте sys.sql_dependencies в SQL Server (оттеглен е)

  4. Entity Framework - One-to-One - ReferentialConstraint се съпоставя към колона, генерирана от магазина

  5. Как да се свържа с база данни на SQL Server в CodeIgniter?