I have a table with the user and DateTime ( format: 12-OCT-22 01.15.23.000 AM). I need to get the user's count based on week, month, quarter, and year.
Like how many users per week, month, quarter, and year. In addition, to that eliminate duplicate records ( for example if a user's id registers twice in a week on the table records, we need to consider only one user) as well.
Need to write the SQL query for this.
ID1 12-OCT-22 01:40:56.880 AM
ID8 12-OCT-22 01:40:56.880 AM
ID6 12-OCT-22 01:40:56.880 AM
ID7 12-OCT-22 01:39:56.880 AM
ID4 12-OCT-22 01:38:56.880 AM
ID10 11-OCT-22 01:37:56.880 PM
ID43 11-OCT-22 01:36:56.880 PM
ID72 11-OCT-22 01:35:56.880 PM
.
.
.
Etc.
Note: I'm using PLSQL application and Oracle DB.
CodePudding user response:
To group by year try the code below, where T is the table that holds your data:
SELECT
TO_CHAR(DateTime, 'YYYY'), COUNT(*)
FROM T
GROUP BY
TO_CHAR(DateTime, 'YYYY')
To group by week, replace YYYY with WW.
To group by month, replace YYYY with MM.
To group by quarter, replace YYYY with Q.
To count the distinct number of users then replace COUNT(*) with COUNT(DISTINCT USER_ID)
If my answer covers you, then please accept it.
CodePudding user response:
Use conditional aggregation:
SELECT userid,
COUNT(1) AS count_for_previous_12_months,
COUNT(CASE WHEN datetime >= TRUNC(SYSDATE, 'YYYY') THEN 1 END) AS count_for_current_year,
COUNT(CASE WHEN datetime >= TRUNC(SYSDATE, 'Q') THEN 1 END) AS count_for_current_quarter,
COUNT(CASE WHEN datetime >= ADD_MONTHS(TRUNC(SYSDATE), -1) THEN 1 END) AS count_for_previous_month,
COUNT(CASE WHEN datetime >= TRUNC(SYSDATE, 'MM') THEN 1 END) AS count_for_current_month,
COUNT(CASE WHEN datetime >= TRUNC(SYSDATE) - INTERVAL '7' DAY THEN 1 END) AS count_for_previous_seven_days,
COUNT(CASE WHEN datetime >= TRUNC(SYSDATE, 'IW') THEN 1 END) AS count_for_current_iso_week
FROM table_name
WHERE datetime > ADD_MONTHS(SYSDATE, -12)
AND datetime <= SYSDATE
GROUP BY userid
If you want to remove duplicates in each week then aggregate by user and week first and then count afterwards:
SELECT userid,
COUNT(1) AS count_for_previous_12_months,
COUNT(CASE WHEN datetime >= TRUNC(SYSDATE, 'YYYY') THEN 1 END) AS count_for_current_year,
COUNT(CASE WHEN datetime >= TRUNC(SYSDATE, 'Q') THEN 1 END) AS count_for_current_quarter,
COUNT(CASE WHEN datetime >= ADD_MONTHS(TRUNC(SYSDATE), -1) THEN 1 END) AS count_for_previous_month,
COUNT(CASE WHEN datetime >= TRUNC(SYSDATE, 'MM') THEN 1 END) AS count_for_current_month,
COUNT(CASE WHEN datetime >= TRUNC(SYSDATE) - INTERVAL '7' DAY THEN 1 END) AS count_for_previous_seven_days,
COUNT(CASE WHEN datetime >= TRUNC(SYSDATE, 'IW') THEN 1 END) AS count_for_current_iso_week
FROM (
SELECT userid,
-- Remove duplicates for each week and set the datetime as the latest in each week
MAX(datetime) AS datetime
FROM table_name
GROUP BY userid, TRUNC(datetime, 'IW')
)
WHERE datetime > ADD_MONTHS(SYSDATE, -12)
AND datetime <= SYSDATE
GROUP BY userid
