【问题标题】:SQL Query for sorting and getting unique count用于排序和获取唯一计数的 SQL 查询
【发布时间】:2021-03-28 00:53:33
【问题描述】:

我有一张包含以下详细信息的表格

Customer Deal DealStage
A D1 Lost
A D2 Won
A D3 Contacted
B D4 Conatcted
B D5 Lost
C D6 Lost
D D7 Lost

我必须开发一个查询,以便为每个客户获取唯一的最高阶段。阶段优先级为赢 > 联系 > 输。例如,A 有三笔交易,分别是赢、输和已联系。所以我应该考虑赢。同样联系了 B 和丢失了 C 和 D

是否有可能得到类似的输出

Customer Highets Stage
A Won
B Contacted
C Lost
D Lost

这样,我可以生成一个看起来像这样的数据透视表

Stage CustomerCount
Won 1
Contacted 1
Lost 2

提前致谢

【问题讨论】:

  • 是的,当然这是可能的。它被称为聚合。不过,我要做的第一件事是更改数据模型。为交易阶段添加一个表格。这有两个优点:(1) 没有拼写错误('Conatcted' vs. 'Contacted'),(2) 您可以添加排名列,以便 DBMS 知道哪个阶段排名高于另一个。
  • @Strawberry 实际上,我在几秒钟内就完全清楚了这个问题。下面非常快速(且正确)的 2 个答案似乎也证实了这一点。

标签: mysql sql count aggregate-functions


【解决方案1】:

使用windows函数如下:

select * from
(select t.*, 
        row_number() over (partition by customer 
                           order by case when dealstage = 'Won' then 1 
                                         when dealstage = 'Contacted' then 2
                                         when dealstage = 'Lost' then 3 
                                    end
        ) as rn
   from your_table t)
 where rn = 1;

【讨论】:

  • 谢谢@Popeye。我会检查这个
【解决方案2】:

一个选项使用聚合和field()

select customer,
    case min(field(deal_stage, 'Won', 'Contacted', 'Lost'))
        when 1 then 'Won'
        when 2 then 'Contacted'
        when 3 then 'Lost'
    end as highest_stage
from mytable
group by customer

其实我们可以把它和elt()结合起来:

select customer,
    elt(
        min(field(deal_stage, 'Won', 'Contacted', 'Lost')), 
        'Won', 'Contacted', 'Lost'
    ) as highest_stage
from mytable
group by customer

然后您可以使用另一个聚合级别生成最终结果:

select highest_stage, count(*)
from (
    select customer,
        elt(
            min(field(deal_stage, 'Won', 'Contacted', 'Lost')), 
            'Won', 'Contacted', 'Lost'
        ) as highest_stage
    from mytable
    group by customer
) t
group by highest_stage

【讨论】:

  • 很好地使用FIELD
  • @TimBiegeleisen:谢谢。 ELT() 也很方便,请参阅我的更新。
  • 如果我想在今年的两列中显示结果,我该如何获得?我使用了现场方法。例如,我应该在一列中分别获取 2019 年的客户计数,在下一列中分别获取 2020 年的客户计数。请帮助@GMB
  • @user12490809:您的数据中没有任何与日期相关的内容,所以我无法确定。我建议为此提出一个新问题,提供适当的样本数据和所需的结果。
  • 我已经编辑了这个问题。请立即检查@GMB
【解决方案3】:

这实际上是两个不同的问题。事实上,我会为这两种方法推荐不同的方法。首先,条件聚合:

select customer, 
       coalesce(max(case when state = 'Won' then state end),
                max(case when state = 'Contacted' then state end),
                max(case when state = 'Lost' then state end)
               ) as biggest_state                
from t
group by customer;

但是,对于您的最终结果,我建议使用相关子查询:

select t.state, count(*)
from t
where t.state = (select t2.state
                 from t2
                 where t2.customer = t.customer
                 order by field(state, 'Won', 'Contact', 'Lost')
                 limit 1
                )
group by t.state;

注意:这假设原始数据没有重复的行。如果是这样,那么count(distinct) 就是一种调整。

【讨论】:

    猜你喜欢
    • 2020-09-09
    • 1970-01-01
    • 2020-11-09
    • 1970-01-01
    • 2022-01-17
    • 1970-01-01
    • 2021-07-17
    • 2021-04-25
    • 2021-01-02
    相关资源
    最近更新 更多