Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Konsolidujące wiersze tabeli MySQL z nakładającymi się zakresami dat

Jednym ze sposobów na to jest użycie skorelowanych podzapytań:

SELECT DISTINCT
       (SELECT MIN(opens)
       FROM mytable AS t2
       WHERE t2.opens <= t1.closes AND t2.closes >= t1.opens) AS start,
       (SELECT MAX(closes)
       FROM mytable AS t2
       WHERE t2.opens <= t1.closes AND t2.closes >= t1.opens) AS end       
FROM mytable AS t1
ORDER BY opens

WHERE predykaty skorelowanych podzapytań:

t2.opens <= t1.closes AND t2.closes >= t1.opens

zwraca wszystkie nakładające się rekordy związane z bieżącym rekordem. Wykonując agregację jednego z tych rekordów możemy znaleźć daty rozpoczęcia/zakończenia każdego interwału:data rozpoczęcia interwału to minimum opens data między wszystkimi nakładającymi się rekordami, podczas gdy data zakończenia to maksymalne closes data.

Pokaz tutaj

EDYTUJ:

Powyższe rozwiązanie nie będzie działać z zestawem interwałów, takim jak:

1. |-----------|
2. |----|
3.           |-----|

Nr rekordu 2, po przetworzeniu da wadliwy interwał początkowy/końcowy.

Oto rozwiązanie wykorzystujące zmienne:

SELECT MIN(start) AS start, MAX(end) AS end
FROM (
  SELECT @grp := IF(@start = '1900-01-01' OR 
                   (opens <= @end AND closes >= @start), @grp, @grp+1) AS grp,        
         @start := IF(@start = '1900-01-01', opens, 
                      IF(opens <= @end AND closes >= @start, 
                         IF (@start < opens, @start, opens), opens)) AS start,
         @end := IF(@end = '1900-01-01', closes, 
                    IF (opens <= @end AND closes >= @start, 
                      IF (@end > closes, @end, closes), closes)) AS end                 
  FROM mytable
  CROSS JOIN (SELECT @grp := 1, @start := '1900-01-01', @end := '1900-01-01') AS vars
  ORDER BY opens, DATEDIFF(closes, opens) DESC) AS t
GROUP BY grp

Pomysł polega na tym, aby zacząć od najbardziej po lewej stronie opens/closes interwał. Zmienne @start , @end są używane do propagowania stopniowo rozszerzającego się (w miarę przetwarzania nowych nakładających się wierszy) skonsolidowanego interwału w dół łańcucha interwałów. Po napotkaniu nienakładającego się interwału [@start - @end] jest inicjowany tak, aby pasował do tego nowego interwału i grp jest zwiększany o jeden.

Pokaz tutaj




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Utwórz ulubiony widok listy ze wspólnymi preferencjami

  2. Jak oszczędzać, obsługiwać łączną kwotę zamówienia w zamówieniu, schemacie orderDetails?

  3. Jak uzyskać dane z bieżącego tygodnia w MySQL?

  4. Wydajność zapytań w dwóch bazach mysql na tym samym serwerze?

  5. Wiele instrukcji wstawiania w pojedynczym ODBC ExecuteNonQuery (C#)