繁体   English   中英

Select 不同的 customer_id

[英]Select distinct customer_id

我想计算article_id级别的每个store_id

  • 有多少共享article_id's分别首先到达 store_A 和 store_B。

  • 如果针对arrival_timestamp < store_B 的文章_id article_id=2的到达时间戳(即文章首先到达 store_A),那么我们将 store_A 计为 1,将 store_B 计为 0

请参阅以下示例:

主表


arrival_timestamp           article_id   store_id

2019-04-01 11:04             2            A
2019-04-01 13:12             2            B
2019-04-01 08:24             4            A
2019-04-01 10:24             4            B
2019-04-10 07:00             7            A
2019-04-10 10:14             7            B
2019-04-23 07:34             9            A
2019-04-23 05:52             9            B

Output表


storeA_count_first_articles     storeB_count_first_articles
3                                1

您可以使用两个级别的聚合:

select
    sum(case when arrival_timestamp_a < arrival_timestamp_b then 1 else 0 end) storeA_count_first_articles,
    sum(case when arrival_timestamp_b < arrival_timestamp_a then 1 else 0 end) storeB_count_first_articles
from (
    select 
        article_id,
        min(case when store_id = 'A' then arrival_timestamp end) arrival_timestamp_a,
        min(case when store_id = 'B' then arrival_timestamp end) arrival_timestamp_b
    from mytable
    group by article_id
) t

子查询使用条件聚合来计算每篇文章在 eacn 商店中的首次到达日期。 然后,外部查询比较每篇文章的初到时间戳并产生最终结果。

另一个选项使用row_number() ,它避免了子查询中的条件逻辑和聚合:

select 
    sum(case when store_id = 'A' then 1 else 0 end) storeA_count_first_articles,
    sum(case when store_id = 'B' then 1 else 0 end) storeB_count_first_articles
from (
    select 
        t.*, 
        row_number() over(partition by article_id order by arrival_timestamp) rn
    from mytable t
) t
where rn = 1

我不熟悉 Presto,但我认为这应该根据他们的文档工作。 这个答案是一个通用的解决方案,不需要在查询中专门命名 Store A 和 Store B。

SELECT
    q.first_store_id AS store_id,
    COUNT(*) AS count_first_articles
FROM
    (
        SELECT
            article_id,
            first_value( store_id ) OVER ( ORDER BY arrival_timestamp ) AS first_store_id
        FROM
            table
        GROUP BY
            article_id
    ) AS q
GROUP BY
    first_store_id

这适用于任意数量的store_id值,而无需手动定义每一列 - 因为结果是面向行而不是面向列的,所以它们更容易在应用程序代码中处理。 如果您仍然想要命名列,您可以在外部查询中执行此操作或使用PIVOT / UNPIVOT (嗯,显然 Presto 还不支持 PIVOT - 但您仍然可以在应用程序代码中执行此操作)

你会得到这样的结果:

store_id        count_first_articles
      A                            3
      B                            1

神奇之处在于first_value ,它是 Window Function ,Presto 内置了一组不错的 window 函数。

要将基于行的结果转换为基于列的原始示例 output,请执行以下操作:

SELECT
    SUM( CASE WHEN q2.store_id = 'A' THEN q2.count_first_articles END ) AS storeA_count_first_articles,
    SUM( CASE WHEN q2.store_id = 'B' THEN q2.count_first_articles END ) AS storeB_count_first_articles
FROM
    (
        SELECT
            q.first_store_id AS store_id,
            COUNT(*) AS count_first_articles
        FROM
            (
                SELECT
                    article_id,
                    first_value( store_id ) OVER ( ORDER BY arrival_timestamp ) AS first_store_id
                FROM
                    table
                GROUP BY
                    article_id
            ) AS q
        GROUP BY
            first_store_id
    ) AS q2

给予:

storeA_count_first_articles     storeB_count_first_articles
3                                1

虽然这个答案表面上比其他答案更复杂(嗯,更嵌套),但它是一个通用解决方案,当您想查看除'A''B'之外的更多商店时,它不需要修改。

您可以使用两个级别的聚合。 一种方法是:

select sum(case when first_store_id = 'A' then 1 else 0 end) as first_a,
       sum(case when first_store_id = 'B' then 1 else 0 end) as first_b       
from (select distinct article_id,
             first_value(store_id) over (partition by article_id order by arrival_timestamp) as first_store_id
      from t
     ) t;

注意:为了方便,内部聚合使用select distinct 外部聚合不使用group by因为您只需要结果集中的一行。

这也可以使用min_by()和显式聚合在 Presto 中编写:

select sum(case when first_store_id = 'A' then 1 else 0 end) as first_a,
       sum(case when first_store_id = 'B' then 1 else 0 end) as first_b       
from (select article_id, min_by(store_id, arrival_timestamp) as first_store_id
      from t
      group by article_id
     ) t;

注意:这两个查询都假定您没有其他商店。 如果您这样做并且您只关心这两个,那么将where store_id in ('A', 'B')添加到查询中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM