I am trying to count, for each id
, the number of distinct app
downloaded by the user, grouping the count by category. An example of the separate queries are as such:
SELECT id
,COUNT(DISTINCT app) AS gaming_apps
FROM apps_table
WHERE app IN ('Clash of Clans', 'Valorant', 'PUBG')
GROUP BY id
SELECT id
,COUNT(DISTINCT app) AS msg_apps
FROM apps_table
WHERE app IN ('Telegram', 'WhatsApp', 'Signal', 'FBMessenger')
GROUP BY id
SELECT id
,COUNT(DISTINCT app) AS fin_apps
FROM apps_table
WHERE app IN ('Yahoo Finance', 'Robinhood')
GROUP BY id
Ideally, I would want to return a table with the columns id
gaming_apps
msg_apps
fin_apps
. I thought about LEFT JOIN
the 3 queries together but I am not sure how, and wrapping each as a subquery would be too unwieldy.
I also tried this, to no avail because a new row is inserted per download or app update:
SELECT id
,COUNT(CASE WHEN app IN ('Clash of Clans', 'Valorant', 'PUBG') THEN 1 ELSE NULL END) AS gaming_apps
,COUNT(CASE WHEN app IN ('Telegram', 'WhatsApp', 'Signal', 'FBMessenger') THEN 1 ELSE NULL END) AS msg_apps
,COUNT(CASE WHEN app IN ('Yahoo Finance', 'Robinhood') THEN 1 ELSE NULL END) AS fin_apps
FROM apps_table
GROUP BY id
3
Answers
I figured out that adding
OVER (PARTITION BY id)
also works in counting only distinct records (not sure why?), albeit returning duplicate rows of the same values depending on how manyapp
entries eachid
has in the table. WithoutOVER (PARTITION BY id)
, it will simply count the matches without consideration of distinct values, inflating the number if theid
has multiple entries of the sameapp
.To remove the duplicates, I then wrap the results as a subquery and
SELECT DISTINCT
or usingROW_NUMBER() OVER (PARTITION BY id)
to create a ranking to then filter with.You are close, you can use SUM instead of count in your query.
I think this should work. if it doesnt work then, like you said do a left join.
If you want distinct counts, then use
count(distinct)
:Note that
ELSE NULL
is redundant, becauseNULL
is the default value if there are no matches in theCASE
expression.