sql >> Databáze >  >> RDS >> Sqlserver

Mohu použít SQL Server CTE ke sloučení protínajících se dat?

Dokončit přepsání:

;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

Nyní vytváří požadovaný výsledek a opravdu pokrývá všechny možné případy, včetně oddělených podskupin a duplikátů. Podívejte se na komentáře k testovacím datům v pracovní ukázka na data.SE .

  • CTE 1
    Najděte (jedinečné!) body v čase, kde začíná nová skupina překrývajících se intervalů.

  • CTE 2
    Počítejte začátek nové skupiny až do (včetně) každého jednotlivého intervalu, čímž vytvoříte jedinečné číslo skupiny na uživatele.

  • Konečný SELECT
    Sloučit skupiny, vybrat dřívější začátek a konec pro skupiny.

Potýkal jsem se s určitými potížemi, protože funkce okna T-SQL max() nebo sum() nepřijímejte ORDER BY klauzule v okně. Mohou vypočítat pouze jednu hodnotu na oddíl, což znemožňuje vypočítat průběžný součet / počet na oddíl. Fungovalo by to v PostgreSQL nebo Oracle (ale ne v MySQL, samozřejmě - nemá ani okenní funkce, ani CTE).

Konečné řešení využívá jeden CTE navíc a mělo by být stejně rychlé.



  1. Určení více relací one-to-many mezi tabulkami v režimu spánku

  2. Ekvivalent Postgresql GROUP_CONCAT?

  3. PostgreSQL:nejlepší způsob, jak spojit malé podmnožiny velkých tabulek

  4. Jak se vzdáleně připojit k databázi MySQL umístěné na našem sdíleném serveru