Reputation: 33
I have one table like below at AWS Timeseries:
tracking_id | measure_value::varchar | measure_value::bigint | measure_name |
---|---|---|---|
269 | - | 48 | age |
269 | Male | - | gender |
I want to filter it to genders and age range like:
age_range | male_count | female_count |
---|---|---|
0-12 | 15 | 12 |
13-17 | 25 | 17 |
I already have a query that:
WITH
genderTable AS (SELECT device_identifier, tracking_id, measure_value::varchar as gender FROM "comp_41"."Visqa18f" WHERE device_identifier='visdemo3' AND measure_name='gender' AND tracking_id IS NOT NULL AND time BETWEEN '2021-03-01 10:30:00' AND '2021-03-01 10:56:00' ORDER BY tracking_id),
ageTable AS (SELECT device_identifier, tracking_id, measure_value::bigint as age FROM "comp_41"."Visqa18f" WHERE device_identifier='visdemo3' AND measure_name='age' AND tracking_id IS NOT NULL
AND time BETWEEN '2021-03-01 10:30:00' AND '2021-03-01 10:56:00' ORDER BY tracking_id)
SELECT
SUM(CASE WHEN age > 0 AND age <= 12 AND gender = 'Male' THEN 1 ELSE 0 END) AS "0-12-M",
SUM(CASE WHEN age >= 13 AND age <= 17 AND gender = 'Male' THEN 1 ELSE 0 END) AS "13-17-M",
SUM(CASE WHEN age >= 18 AND age <= 24 AND gender = 'Male' THEN 1 ELSE 0 END) AS "18-24-M",
SUM(CASE WHEN age >= 25 AND age <= 34 AND gender = 'Male' THEN 1 ELSE 0 END) AS "25-34-M",
SUM(CASE WHEN age >= 35 AND age <= 44 AND gender = 'Male' THEN 1 ELSE 0 END) AS "35-44-M",
SUM(CASE WHEN age >= 45 AND age <= 54 AND gender = 'Male' THEN 1 ELSE 0 END) AS "45-54-M",
SUM(CASE WHEN age >= 55 AND gender = 'Male' THEN 1 ELSE 0 END) AS "54-M",
SUM(CASE WHEN age > 0 AND age <= 12 AND gender = 'Female' THEN 1 ELSE 0 END) AS "0-12-F",
SUM(CASE WHEN age >= 13 AND age <= 17 AND gender = 'Female' THEN 1 ELSE 0 END) AS "13-17-F",
SUM(CASE WHEN age >= 18 AND age <= 24 AND gender = 'Female' THEN 1 ELSE 0 END) AS "18-24-F",
SUM(CASE WHEN age >= 25 AND age <= 34 AND gender = 'Female' THEN 1 ELSE 0 END) AS "25-34-F",
SUM(CASE WHEN age >= 35 AND age <= 44 AND gender = 'Female' THEN 1 ELSE 0 END) AS "35-44-F",
SUM(CASE WHEN age >= 45 AND age <= 54 AND gender = 'Female' THEN 1 ELSE 0 END) AS "45-54-F",
SUM(CASE WHEN age >= 55 AND gender = 'Female' THEN 1 ELSE 0 END) AS "54-F"
FROM ageTable, genderTable WHERE ageTable.tracking_id = genderTable.tracking_id
I want to do it with shorter and better optimized query and decided to do it with GROUP BY for age range How can I use GROUP BY for filter on AGE RANGE?
Upvotes: 1
Views: 125
Reputation: 23676
This should do it:
SELECT
CASE
WHEN age BETWEEN 0 and 12 THEN '0 - 12'
WHEN age BETWEEN 13 and 17 THEN '13 - 17'
...
END as age_range,
COUNT(*) FILTER (WHERE gender = 'Male') as male_count,
COUNT(*) FILTER (WHERE gender = 'Female') as female_count
FROM (
SELECT
tracking_id,
MAX(measure_value_gender) as gender,
MAX(measure_value_age) as age
FROM mytable
GROUP BY tracking_id
) s
GROUP BY age_range
If you don't want to use the FILTER
clause, you can, of course, use your SUM(CASE WHEN gender = 'Male' THEN 1 ELSE 0 END)
construct as well.
Upvotes: 2