你好,我无法在以下情况下取得好成绩:
我有一张像这样的表:
UserID | Label
-------- ------
1 | Private
1 | Public
2 | Private
3 | Hidden
4 | Public
5 | Hidden
如果用户有以下指定,我希望发生以下情况:
私人和隐藏受到同样的打击:让我们说商务
公众:BtoC
公共和私人和/或隐藏:双方
所以最后我有count(DISTINCT UserID)
Business 3
BtoC 1
both 1
我尝试使用CASE WHEN
,但它不起作用我的当前总查询如下所示:
SELECT gen_month,
count(DISTINCT cu.id) as leads,
a.label
FROM generate_series(DATE_TRUNC('month', CURRENT_DATE::date - 96*INTERVAL '1 month'), CURRENT_DATE::date, '1 month') m(gen_month)
LEFT OUTER JOIN company_user AS cu
ON (date_trunc('month', cu.creation_date) = date_trunc('month', gen_month))
LEFT JOIN user u
ON u.user_id = cu.id
LEFT join user_account_status as uas
on cu.id = uas.user_id
LEFT JOIN account as a
on uas.account_id = a.id
where gen_month >= DATE_TRUNC('month',NOW() - INTERVAL '5 months')
group by m.gen_month, a.label
order by gen_month
所以现在我的主要问题是计数出现在每个属性中一次。 如何使用户ID仅在条件情况下计数一次当用户_id出现时公共和(私有或隐藏)那么计数(DISTINCT user_id)为两者?
另外:它的mySQL mariaDB和postgreSQL。但首先我会对Postgres感到满意
答案 0 :(得分:0)
这不是在您的总查询中实现的,但是对于每个类别的用户计数,您可以:
is_admin
答案 1 :(得分:0)
with
my_table(user_id, label) as (values
(1,'Private'),
(1,'Public'),
(2,'Private'),
(3,'Hidden'),
(4,'Public'),
(5,'Hidden')),
t as (
select
user_id,
string_agg('{'||label||'}', '') as labels
from my_table
group by user_id),
tt as (
select
user_id,
labels,
case
when
position('{Public}' in labels) > 0 and (position('{Private}' in labels) > 0 or position('{Hidden}' in labels) > 0) then 'Both'
when
position('{Private}' in labels) > 0 or position('{Hidden}' in labels) > 0 then 'Business'
when
position('{Public}' in labels) > 0 then 'BtoC'
end as kind
from t)
select kind, count(*) from tt group by kind;
对于MariaDB,使用GROUP_CONCAT()
而不是PostgreSQL string_agg()
。
请注意,case
语句按出现顺序检查条件,并返回第一个满足条件的值。
PS:使用PostgreSQL的数组,条件会更优雅。