This is my first post, so I hope I've posted this one correctly.
I want to count the number of active customers per day, the last 30 days.
In the first column I want to print today, and the last 29 days. This I have done with
select distinct trunc(sysdate-dayincrement, 'DD') AS DATES
from (
select level as dayincrement
from dual
connect by level <= 30
)
I've picked it up here at stackoverflow, and it works perfectly. I can even extend the number of days returned to ex. 365 days. Perfect!
I also have a table that looks like this
|Cust# | Start date | End date |
| 1000 | 01.01.2015 | 31.12.2015|
| 1001 | 02.01.2015 | 31.12.2016|
| 1002 | 02.01.2015 | 31.03.2015|
| 1003 | 03.01.2015 | 31.08.2015|
This is where I feel the problem starts
I would like to get this result:
| Dates | # of cust |
|04.01.2015| 4 |
|03.01.2015| 4 |
|02.01.2015| 3 |
|01.01.2015| 1 |
Here the query would count 1 if:
Else count 0.
I just don't know how to structure the query.
I tried this, but it didn't work.
count(
IF ENDDATE <= DATES THEN
IF STARTDATE >= DATES THEN 1 ELSE 0 END IF
ELSE
0
END IF
) AS CUST
Any ideas?
You could write a CASE expression equivalent to your IF-ELSE construct.
For example,
SQL> SELECT COUNT(
2 CASE
3 WHEN hiredate <= sysdate
4 THEN 1
5 ELSE 0
6 END ) AS CUST
7 FROM emp;
CUST
----------
14
SQL>
However, looking at your desired output, it seems, you just need to use COUNT and GROUP BY . The date conditions should be in the filter predicate .
For example,
SELECT dates, COUNT(*)
FROM table_name
WHERE dates BETWEEN start_date AND end_date
GROUP BY dates;
The following produces the results you're looking for. I had change the date generator to start on 04-JAN- 2015 instead of SYSDATE (which is, of course, in the year 2016 ), and to use LEVEL-1
to include 'current' day:
WITH CUSTS AS (SELECT 1000 AS CUST_NO, TO_DATE('01-JAN-2015', 'DD-MON-YYYY') AS START_DATE, TO_DATE('31-DEC-2015', 'DD-MON-YYYY') AS END_DATE FROM DUAL UNION ALL
SELECT 1001 AS CUST_NO, TO_DATE('02-JAN-2015', 'DD-MON-YYYY') AS START_DATE, TO_DATE('31-DEC-2016', 'DD-MON-YYYY') AS END_DATE FROM DUAL UNION ALL
SELECT 1002 AS CUST_NO, TO_DATE('02-JAN-2015', 'DD-MON-YYYY') AS START_DATE, TO_DATE('31-MAR-2015', 'DD-MON-YYYY') AS END_DATE FROM DUAL UNION ALL
SELECT 1003 AS CUST_NO, TO_DATE('03-JAN-2015', 'DD-MON-YYYY') AS START_DATE, TO_DATE('31-AUG-2015', 'DD-MON-YYYY') AS END_DATE FROM DUAL ),
DATES AS (SELECT DISTINCT TRUNC(TO_DATE('04-JAN-2015', 'DD-MON-YYYY') - DAYINCREMENT, 'DD') AS DT
FROM (SELECT LEVEL-1 AS DAYINCREMENT
FROM DUAL
CONNECT BY LEVEL <= 30))
SELECT d.DT, COUNT(*)
FROM CUSTS c
CROSS JOIN DATES d
WHERE d.DT BETWEEN c.START_DATE AND c.END_DATE
GROUP BY d.DT
ORDER BY DT DESC
Best of luck.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.