如何选择前三个订单与特定值匹配的客户?

时间:2019-03-20 10:56:40

标签: sql google-bigquery

说我有一个表shop_orders,我想查询所有的customer_id,其中前三个order_type分别是“ Book”,“ Coffee”和“ Pen”。

源表如下所示:

<ng-container *ngIf="person.nom"> // *ngIf="person"
  {{ person.name}}
</ng-container>

由于用户6455的前三个订单是“书”,“咖啡”和“笔”,因此查询应返回:

{ personId: 2, name: Fox } // no type: 'man'

我正在为此使用BigQuery。

3 个答案:

答案 0 :(得分:1)

以下是用于BigQuery标准SQL

#standardSQL
SELECT customer_id
FROM `project.dataset.shop_orders`
GROUP BY customer_id
HAVING STRING_AGG(order_type ORDER BY order_time LIMIT 3) = 'Book,Coffee,Pen'  

您可以使用问题中的示例数据来进行测试,如上示例所示

#standardSQL
WITH `project.dataset.shop_orders` AS (
  SELECT 6872 customer_id, 'Coffee' order_type, '2018-04-06 15:06' order_time UNION ALL
  SELECT 6455, 'Book', '2018-04-06 15:08' UNION ALL
  SELECT 6872, 'Coffee', '2018-04-06 19:12' UNION ALL
  SELECT 6455, 'Coffee', '2018-04-07 15:08' UNION ALL
  SELECT 5217, 'Pen', '2018-04-08 09:11' UNION ALL
  SELECT 5217, 'Book', '2018-04-08 10:55' UNION ALL
  SELECT 6455, 'Pen', '2018-04-09 05:22' UNION ALL
  SELECT 6455, 'Coffee', '2018-04-09 07:46'
)
SELECT customer_id
FROM `project.dataset.shop_orders`
GROUP BY customer_id
HAVING STRING_AGG(order_type ORDER BY order_time LIMIT 3) = 'Book,Coffee,Pen' 

有结果

Row customer_id  
1   6455     

答案 1 :(得分:0)

嗯。 。 。

select customer_id
from t
group by customer_id
having array_to_string(array_agg(order_type order by order_time limit 3), ',') = 'Book,Coffee,Pen';

代码如下:

with t as (
      select 6872 as customer_id, 'Coffee' as order_type, '2018-04-06 15:06' as order_time union all
      select 6455, 'Book', '2018-04-06 15:08' union all
      select 6872, 'Coffee', '2018-04-06 19:12' union all
      select 6455, 'Coffee', '2018-04-07 15:08' union all
      select 5217, 'Pen', '2018-04-08 09:11' union all
      select 5217, 'Book', '2018-04-08 10:55' union all
      select 6455, 'Pen', '2018-04-09 05:22' union all
      select 6455, 'Coffee', '2018-04-09 07:46'
     )
select customer_id, array_to_string(array_agg(order_type order by order_time limit 3), ',')
from t
group by customer_id
having array_to_string(array_agg(order_type order by order_time limit 3), ',') = 'Book,Coffee,Pen';

答案 2 :(得分:0)

您可以使用existsrow_number()

  with cte as
 (
  select *,row_number()over(partition by customer_id order by order_time ) rn
  from table    
 ), cte1 as
 (
  select * from cte where rn<=3
 ) select * from cte1 t1
   where exists( select 1 from cte1 t2 where t1.customer_id=t2.customer_id
                and t2.rn=1 and t2.order_type='Book'
                )
              and exists ( select 1 from cte1 t2
              where t1.customer_id=t2.customer_id
                and t2.rn=2 and t2.order_type='Coffee'
                )
               and exists ( select 1 from cte1 t2
              where t1.customer_id=t2.customer_id
                and t2.rn=3 and t2.order_type='Pen'

            )

输出

customer_id     order_type  order_time  rn
6455    Book    2018-04-06 15:08        1
6455    Coffee  2018-04-07 15:08        2
6455    Pen     2018-04-09 05:22        3

demo in sql server but will work bigquery also