Oracle
 sql >> Baza danych >  >> RDS >> Oracle

policz liczbę wierszy występujących dla każdej daty w zakresie dat kolumny

WITH    q AS
        (
        SELECT  (
                SELECT  MIN(start_date)
                FROM    mytable
                ) + level - 1 AS mydate
        FROM    dual
        CONNECT BY
                level <= (
                SELECT  MAX(end_date) - MIN(start_date)
                FROM    mytable
                )
        )
SELECT  group, mydate,
        (
        SELECT  COUNT(*)
        FROM    mytable mi
        WHERE   mi.group = mo.group
                AND q BETWEEN mi.start_date AND mi.end_date
        ) 
FROM    q
CROSS JOIN
        (
        SELECT  DISTINCT group
        FROM    mytable
        ) mo

Aktualizacja:

Lepsze i szybsze zapytanie wykorzystujące funkcje analityczne.

Główną ideą jest to, że liczba zakresów zawierających każdą datę jest różnicą przed liczbą zakresów rozpoczętych przed tą datą i liczbą zakresów, które zakończyły się przed tą datą.

SELECT  cur_date,
        grouper,
        SUM(COALESCE(scnt, 0) - COALESCE(ecnt, 0)) OVER (PARTITION BY grouper ORDER BY cur_date) AS ranges
FROM    (
        SELECT  (
                SELECT  MIN(start_date)
                FROM    t_range
                ) + level - 1 AS cur_date
        FROM    dual
        CONNECT BY
                level <=
                (
                SELECT  MAX(end_date)
                FROM    t_range
                ) -
                (
                SELECT  MIN(start_date)
                FROM    t_range
                ) + 1
        ) dates
CROSS JOIN
        (
        SELECT  DISTINCT grouper AS grouper
        FROM    t_range
        ) groups
LEFT JOIN
        (
        SELECT  grouper AS sgrp, start_date, COUNT(*) AS scnt
        FROM    t_range
        GROUP BY
                grouper, start_date
        ) starts
ON      sgrp = grouper
        AND start_date = cur_date
LEFT JOIN
        (
        SELECT  grouper AS egrp, end_date, COUNT(*) AS ecnt
        FROM    t_range
        GROUP BY
                grouper, end_date
        ) ends
ON      egrp = grouper
        AND end_date = cur_date - 1
ORDER BY
        grouper, cur_date

To zapytanie kończy się w 1 drugi na 1,000,000 wiersze.

Zobacz ten wpis na moim blogu, aby uzyskać więcej informacji:



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Funkcja POWER() w Oracle

  2. Query działa na Oracle 11g, ale nie działa na Oracle 8i

  3. Czy instrukcje DDL zawsze dają niejawne zatwierdzenie, czy można uzyskać niejawne wycofanie?

  4. Mapowanie klucza obcego z niestandardową nazwą kolumny

  5. Wyodrębnianie wierszy z bazy danych, w tym wierszy zależnych