I'm trying to create a query which will put some rows in multiple groups. I'm doing this by generating an array that contains both categories I want to group by.
Here's my query so far (slightly simplified to remove extraneous details but substantially similar to avoid the risk of erroneous changes):
SELECT
case when s.compliant then true else false end as "Compliant",
(consequences ->> 'Face Covering or Respirator'='Required' ) as "Masked",
case
when (consequences ->> 'Face Covering or Respirator'='Required') and s.compliant
then '{"Masked","Compliant"}'
when (consequences->>'Face Covering or Respirator'='Required') then '{"Masked"}'
when s.compliant then '{"Compliant"}'
else '{"Non-compliant"}'
end::text[] as "Category",
COUNT(*) AS "Total"
FROM employees
LEFT JOIN surveys s ON s.uid = employees.uid
GROUP BY s.compliant, "Category", "Masked"
Basically, I want 3 totals in the Totals column, even though these groups are not mutually exclusive:
- those who are compliant (whether they must wear a mask or not!)
- those who must wear a mask and are compliant (all of these people are also in the total for # 1)
- those who are non-compliant
Right now my results are
| Compliant | Masked | Category | Total |
|----------------------------------------------------------------------------|
| true | | {Compliant} | 2 |
| true | true | {Masked,Compliant} | 10 |
| false | | {Non-compliant} | 63,204 |
But I want to group by Array ITEMS instead of ARRAYS, like so:
| Compliant | Masked | Category | Total |
|----------------------------------------------------------------------------|
| true | | Compliant | 12 |
| true | true | Masked | 10 |
| false | | Non-compliant | 63,204 |
(If the data doesn't seem to make sense: a person can be compliant with the policy either by getting jabbed or by agreeing to wear a mask, the only options on the survey. Anyone who has not yet taken the survey is considered non-compliant.)
Note the different total for compliant. How can I get the second result set instead of the first?
surveys a
should besurveys s
. Show table definitions (CREATE TABLE
statements), your Postgres version and some sample data.e.consequences
ors.consequences
? 1:n or 1:1? Are we counting surveys or unique employees?s.consequences
is a JSONB field with consequences of the answers to the survey, in this case potentially the requirement to wear a mask. There should never be more than one survey per employee, but there can easily be zero. The case statementcase when s.compliant then true else false end as "Compliant"
handles the situation where there is no survey yet, to returnfalse
for compliance.