Oracle
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Oracle

đếm số hàng xảy ra cho mỗi ngày trong phạm vi ngày của cột

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

Cập nhật:

Truy vấn tốt hơn và nhanh hơn khi sử dụng các hàm phân tích.

Ý tưởng chính là số lượng phạm vi chứa mỗi ngày là sự khác biệt trước khi số lượng phạm vi bắt đầu trước ngày đó và số lượng phạm vi kết thúc trước ngày đó.

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

Truy vấn này hoàn thành trong 1 thứ hai trên 1,000,000 hàng.

Xem mục này trong blog của tôi để biết thêm chi tiết:



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. chạy mã sql oracle trực tuyến

  2. tìm nạp tên bảng từ một cột cho mệnh đề from

  3. Chỉ mục thời gian không đổi cho cột chuỗi trên cơ sở dữ liệu Oracle

  4. Chuỗi Oracle đến ngày 2013-10-15T20:12:56.24584 + 0100

  5. Oracle 10g:Trích xuất dữ liệu (chọn) từ XML (Loại CLOB)