SQL Fiddle
Oracle 11g R2 架构设置:
CREATE TABLE dataset ( user_id, subscription_id, start_date, end_date, payment_amt ) AS
SELECT 1,1, SYSDATE - 370, SYSDATE - 370 + INTERVAL '1' MONTH, 10 FROM DUAL
UNION ALL SELECT 2,1, SYSDATE - 350, SYSDATE - 350 + INTERVAL '1' MONTH, 10 FROM DUAL
UNION ALL SELECT 3,2, SYSDATE - 345, SYSDATE - 345 + INTERVAL '1' MONTH, 10 FROM DUAL
UNION ALL SELECT 4,3, SYSDATE - 310, SYSDATE - 370 + INTERVAL '1' MONTH, 10 FROM DUAL
UNION ALL SELECT 5,4, SYSDATE - 250, SYSDATE - 250 + INTERVAL '1' MONTH, 10 FROM DUAL
UNION ALL SELECT 6,5, SYSDATE - 250, SYSDATE - 250 + INTERVAL '1' MONTH, 10 FROM DUAL
UNION ALL SELECT 7,6, SYSDATE - 240, SYSDATE - 240 + INTERVAL '1' MONTH, 10 FROM DUAL
UNION ALL SELECT 8,6, SYSDATE - 230, SYSDATE - 230 + INTERVAL '1' MONTH, 10 FROM DUAL
UNION ALL SELECT 9,7, SYSDATE - 100, SYSDATE - 100 + INTERVAL '1' MONTH, 10 FROM DUAL
UNION ALL SELECT 10,8, SYSDATE - 50, SYSDATE - 50 + INTERVAL '1' MONTH, 10 FROM DUAL
UNION ALL SELECT 11,9, SYSDATE - 20, SYSDATE - 20 + INTERVAL '1' MONTH, 10 FROM DUAL
UNION ALL SELECT 12,9, SYSDATE, SYSDATE + INTERVAL '1' MONTH, 10 FROM DUAL;
查询 1:
WITH all_dates_of_year AS (
SELECT TRUNC(SYSDATE) - INTERVAL '1' YEAR + LEVEL - 1 AS day
FROM DUAL
CONNECT BY
TRUNC(SYSDATE) - INTERVAL '1' YEAR + LEVEL - 1 <= TRUNC(SYSDATE)
)
SELECT day,
COUNT( DISTINCT user_id ) AS num_users,
COUNT( DISTINCT subscription_id ) AS num_subs
FROM all_dates_of_year a
LEFT OUTER JOIN
dataset d
ON ( a.day BETWEEN TRUNC( d.start_date ) AND TRUNC( d.end_date ) )
GROUP BY
a.day
Results:
| DAY | NUM_USERS | NUM_SUBS |
|-----------------------------|-----------|----------|
| June, 23 2014 00:00:00 | 1 | 1 |
| June, 24 2014 00:00:00 | 1 | 1 |
| June, 25 2014 00:00:00 | 1 | 1 |
| June, 26 2014 00:00:00 | 1 | 1 |
| June, 27 2014 00:00:00 | 1 | 1 |
| June, 28 2014 00:00:00 | 1 | 1 |
| June, 29 2014 00:00:00 | 1 | 1 |
| June, 30 2014 00:00:00 | 1 | 1 |
| July, 01 2014 00:00:00 | 1 | 1 |
| July, 02 2014 00:00:00 | 1 | 1 |
| July, 03 2014 00:00:00 | 1 | 1 |
| July, 04 2014 00:00:00 | 1 | 1 |
| July, 05 2014 00:00:00 | 1 | 1 |
| July, 06 2014 00:00:00 | 1 | 1 |
| July, 07 2014 00:00:00 | 1 | 1 |
| July, 08 2014 00:00:00 | 2 | 1 |
| July, 09 2014 00:00:00 | 2 | 1 |
| July, 10 2014 00:00:00 | 2 | 1 |
| July, 11 2014 00:00:00 | 2 | 1 |
| July, 12 2014 00:00:00 | 2 | 1 |
| July, 13 2014 00:00:00 | 3 | 2 |
| July, 14 2014 00:00:00 | 3 | 2 |
| July, 15 2014 00:00:00 | 3 | 2 |
| July, 16 2014 00:00:00 | 3 | 2 |
| July, 17 2014 00:00:00 | 3 | 2 |
| July, 18 2014 00:00:00 | 3 | 2 |
| July, 19 2014 00:00:00 | 2 | 2 |
| July, 20 2014 00:00:00 | 2 | 2 |
| July, 21 2014 00:00:00 | 2 | 2 |
| July, 22 2014 00:00:00 | 2 | 2 |
| July, 23 2014 00:00:00 | 2 | 2 |
| July, 24 2014 00:00:00 | 2 | 2 |
| July, 25 2014 00:00:00 | 2 | 2 |
| July, 26 2014 00:00:00 | 2 | 2 |
| July, 27 2014 00:00:00 | 2 | 2 |
| July, 28 2014 00:00:00 | 2 | 2 |
| July, 29 2014 00:00:00 | 2 | 2 |
| July, 30 2014 00:00:00 | 2 | 2 |
| July, 31 2014 00:00:00 | 2 | 2 |
| August, 01 2014 00:00:00 | 2 | 2 |
| August, 02 2014 00:00:00 | 2 | 2 |
| August, 03 2014 00:00:00 | 2 | 2 |
| August, 04 2014 00:00:00 | 2 | 2 |
| August, 05 2014 00:00:00 | 2 | 2 |
| August, 06 2014 00:00:00 | 2 | 2 |
| August, 07 2014 00:00:00 | 2 | 2 |
| August, 08 2014 00:00:00 | 2 | 2 |
| August, 09 2014 00:00:00 | 1 | 1 |
| August, 10 2014 00:00:00 | 1 | 1 |
| August, 11 2014 00:00:00 | 1 | 1 |
| August, 12 2014 00:00:00 | 1 | 1 |
| August, 13 2014 00:00:00 | 1 | 1 |
| August, 14 2014 00:00:00 | 0 | 0 |
| August, 15 2014 00:00:00 | 0 | 0 |
| August, 16 2014 00:00:00 | 0 | 0 |
| August, 17 2014 00:00:00 | 0 | 0 |
| August, 18 2014 00:00:00 | 0 | 0 |
| August, 19 2014 00:00:00 | 0 | 0 |
| August, 20 2014 00:00:00 | 0 | 0 |
...
| June, 21 2015 00:00:00 | 1 | 1 |
| June, 22 2015 00:00:00 | 1 | 1 |
| June, 23 2015 00:00:00 | 2 | 1 |