Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Czy mogę użyć CTE programu SQL Server do scalania przecinających się dat?

Całkowite przepisywanie:

;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

Teraz generuje żądany wynik i naprawdę obejmuje wszystkie możliwe przypadki, w tym rozłączne podgrupy i duplikaty.Zapoznaj się z komentarzami do danych testowych w działająca prezentacja na data.SE .

  • CTE 1
    Znajdź (unikalne!) punkty w czasie, w których zaczyna się nowa grupa nakładających się przedziałów.

  • CTE 2
    Policz początki nowej grupy do (włącznie) każdego indywidualnego interwału, tworząc w ten sposób unikalny numer grupy na użytkownika.

  • Końcowy WYBIERZ
    Połącz grupy, weź wczesny początek i najpóźniejszy koniec dla grup.

Napotkałem pewną trudność, ponieważ funkcje okna T-SQL max() lub sum() nie akceptuj ORDER BY klauzula w oknie. Mogą obliczyć tylko jedną wartość na partycję, co uniemożliwia obliczenie bieżącej sumy / liczby na partycję. Działałby w PostgreSQL lub Oracle (ale oczywiście nie w MySQL - nie ma on ani funkcji okna, ani CTE).

Ostateczne rozwiązanie wykorzystuje jeden dodatkowy CTE i powinno być równie szybkie.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak wstawić ciąg zawierający pojedyncze lub podwójne cudzysłowy

  2. Stronicowanie po stronie serwera w SQL Server

  3. Błąd składni w pobliżu „z” w warunku wyszukiwania pełnotekstowego „kontrola z”

  4. Konwersja ciągu rozdzielanego przecinkami na wiele kolumn w serwerze sql

  5. Czy istnieje coś takiego jak kursor równoległy?