与列表汇总分组依据的问题

时间:2018-09-05 15:49:10

标签: sql amazon-redshift

在使用listagg()的查询中,我尝试为以下内容添加一个子句:split_rep:存在user_id的{​​{1}},以及multi_rep:存在更多profile_type='Split'的子句多于一个user_id

简化的查询(其中-是我要执行的操作):

ap.id

这引发了一个错误,select distinct r.user_id, listagg(distinct ap.rep_code, ', ') within group (order by ap.bill_rate) as rep_code_list --,case when max(ap.profile_type) over (partition by r.user_id)='Split' then 1 else 0 end has_split_rep_code --,case when count(ap.id) over (partition by r.user_id)>1 then 1 else 0 end has_multi_rep_code from representatives r join profiles ap on r.user_id=ap.user_id group by r.user_id profile_type必须位于id中-但是,如果添加了该错误,则会产生错误的输出。不知道为什么listagg不支持window函数,但是知道如何绕过它吗?

样本数据:

group by

所需的输出:

user_id   id   profile_type   rep_code
A         A    Self           AAA
A         B    Self           AAB
B         C    Self           AAC
C         D    Self           AAD
C         E    Split          AAE
D         F    Split          AAF

2 个答案:

答案 0 :(得分:1)

您可以使用OVER

select distinct r.user_id,
  listagg(distinct ap.rep_code, ', ') within group (order by ap.bill_rate)
   over(partition by ap.user_id) as rep_code_list
  -- rest of cols
from representatives r
join profiles ap on r.user_id=ap.user_id;

答案 1 :(得分:1)

我认为您将select distinctgroup by结合使用时感到困惑。这些具体取决于上下文,它们可以做类似的事情。我在下面使用CASE表达式来计算split_rep_code列,并且还为multi_rep_code列添加了逻辑。

select
    r.user_id,
    listagg(ap.rep_code, ', ') within group (order by ap.bill_rate) as rep_code_list,
    case when sum(case when ap.profile_type = 'Split' then 1 else 0 end) > 0
         then 1 else 0 end as split_rep_code,
    case when min(ap.id) <> max(ap.id) then 1 else 0 end as multi_rep_code
from representatives r
inner join profiles ap
    on r.user_id = ap.user_id
group by
    r.user_id;

enter image description here

Demo

请注意,该演示在Postgres中进行,我使用了string_agg而不是Redshift的list_agg,但是原理是相同的。另请注意,Redshift不支持在DISTINCT中使用list_agg。如果确实需要该行为,则可能必须先进行子查询才能删除重复项。