The original table User
ID Created_Date SubmittedAt ApprovedAt
The original table Campaign
User_ID Clicked_At
Now I want to generate a report with columns like
Month Year #Applicants #Submitted #Approved
I wrote queries using postgresql:
SELECT To_char(C.clicked_at, 'MON') AS MON,
Extract(year FROM C.clicked_at) AS YYYY,
CASE
WHEN created_date IS NOT NULL THEN Count(user_id)
END AS APPLICANTS,
CASE
WHEN submittedat IS NOT NULL THEN Count(user_id)
END AS SUBMITTED,
CASE
WHEN approvedat IS NOT NULL THEN Count(user_id)
END AS APPROVED
FROM campaign C,
users U
WHERE C.user_id = U.id
GROUP BY 1,2
I got an error message " u.created_date
must appear in the GROUP BY
clause or be used in an aggregate function. However, I just want my results to be grouped by year
and month
.
First, use proper, explicit JOIN
syntax. Second, if you want to count the number of non-null values, then you can simplify the code:
SELECT TO_CHAR(C.CLICKED_AT, 'MON') AS MON,
EXTRACT(YEAR FROM C.CLICKED_AT) AS YYYY,
COUNT(CREATED_DATE) AS APPLICANTS,
COUNT(SUBMITTEDATE) AS SUBMITTED,
COUNT(APPROVEDAT) AS APPROVED
FROM CAMPAIGN C JOIN
USERS U
ON C.USER_ID = U.ID
GROUP BY 1, 2;
With this simplification, you no longer have any (explicit) conditional logic at all, so the group by
clause is fine.
I would suggest that you combine the month and year and sort the results:
SELECT TO_CHAR(C.CLICKED_AT, 'YYYY-MM') AS yyyymm,
COUNT(CREATED_DATE) AS APPLICANTS,
COUNT(SUBMITTEDATE) AS SUBMITTED,
COUNT(APPROVEDAT) AS APPROVED
FROM CAMPAIGN C JOIN
USERS U
ON C.USER_ID = U.ID
GROUP BY 1
ORDER BY 1;
You need to put your CASE statements within an aggregate function:
SELECT TO_CHAR(C.CLICKED_AT,'MON') AS MON,
EXTRACT(YEAR FROM C.CLICKED_AT) AS YYYY,
COUNT(CASE WHEN CREATED_DATE IS NOT NULL THEN USER_ID END) AS APPLICANTS,
COUNT(CASE WHEN SUBMITTEDAT IS NOT NULL THEN USER_ID END) AS SUBMITTED,
COUNT(CASE WHEN APPROVEDAT IS NOT NULL THEN USER_ID END) AS APPROVED
FROM
CAMPAIGN C
JOIN USERS U ON C.USER_ID = U.ID
GROUP BY 1,2
Notes:
FILTER
clause. JOIN
clause instead of WHERE clause for connecting tables TO_CHAR()
to accept year and month Example:
SELECT TO_CHAR(C.CLICKED_AT,'YYYY-MM') AS date_year_month,
COUNT(CASE WHEN CREATED_DATE IS NOT NULL THEN USER_ID END) AS APPLICANTS,
COUNT(CASE WHEN SUBMITTEDAT IS NOT NULL THEN USER_ID END) AS SUBMITTED,
COUNT(CASE WHEN APPROVEDAT IS NOT NULL THEN USER_ID END) AS APPROVED
FROM
CAMPAIGN C
JOIN USERS U ON C.USER_ID = U.ID
GROUP BY 1
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.