【问题标题】:How can i find rows before a specific value?如何在特定值之前找到行?
【发布时间】:2020-10-04 06:46:12
【问题描述】:

我有下一行,我想做的是选择类型“商店”之前的所有行。我尝试在“where 子句”中使用大小写,但没有得到任何结果。我该怎么做?

|id|visitnumber|type    |
|01|          1|register|
|01|          2|visit   |
|01|          3|visit   |
|01|          4|shop    |
|01|          5|visit   |

比如我要获取的是type="shop"之前的visitnumber。

这将非常有帮助,因为我要做的是获取在大查询的特定事件之前发生的所有操作。

|id|numberofvisits|
|01|             3|

【问题讨论】:

  • 如果有两次shop类型的访问呢?

标签: sql select count google-bigquery window-functions


【解决方案1】:

一种方法使用相关子查询:

select id, count(*)
from t
where visitnumber < (select min(t2.visitnumber) from t t2 where t2.id = t.id and type = 'shop')
group by id;

但是,在 BigQuery 中,我更喜欢使用窗口函数的方法:

select id, countif(visitnumber < visitnumber_shop)
from (select t.*,
             min(case when type = 'shop' then visitnumber end) over (partition by id) as visitnumber_shop
      from t
     ) t
group by id;

这样做的好处是可以保留所有ids,即使是那些没有“商店”类型的人。

【讨论】:

    【解决方案2】:

    一个选项使用子查询进行过滤:

    select id, count(*) number_of_visits
    from mytable t
    where t.visit_number < (
        select min(t1.visit_number)
        from mytable t
        where t1.id = t.id and t1.type = 'shop'
    )
    group by id
    

    你也可以使用窗口函数:

    select id, count(*) number_of_visits
    from (
        select 
            t.*, 
            countif(type = 'shop') over(partition by id order by visit_number) has_shop
        from mytable t
    ) t
    where has_shop = 0
    group by id
    

    【讨论】:

      【解决方案3】:

      以下选项适用于 BigQuery 标准 SQL

      #standardSQL
      SELECT id, 
        ARRAY_LENGTH(SPLIT(REGEXP_EXTRACT(',' || STRING_AGG(type ORDER BY visitnumber), r'(.*?),shop'))) - 1 AS number_of_visits_before_first_shop
      FROM `project.dataset.table`
      GROUP BY id   
      

      你可以像下面的例子一样使用虚拟数据测试,玩上面的例子

      #standardSQL
      WITH `project.dataset.table` AS (
        SELECT '01' id, 1 visitnumber, 'register' type UNION ALL
        SELECT '01', 2, 'visit' UNION ALL
        SELECT '01', 3, 'visit' UNION ALL
        SELECT '01', 4, 'shop' UNION ALL
        SELECT '01', 5, 'visit' UNION ALL
        SELECT '02', 1, 'register' UNION ALL
        SELECT '02', 2, 'visit' UNION ALL
        SELECT '02', 3, 'visit' UNION ALL
        SELECT '03', 1, 'shop' UNION ALL
        SELECT '03', 2, 'shop' UNION ALL
        SELECT '03', 3, 'visit' 
      )
      SELECT id, 
        ARRAY_LENGTH(SPLIT(REGEXP_EXTRACT(',' || STRING_AGG(type ORDER BY visitnumber), r'(.*?),shop'))) - 1 AS number_of_visits_before_first_shop
      FROM `project.dataset.table`
      GROUP BY id    
      

      结果

      Row id  number_of_visits_before_first_shop   
      1   01  3    
      2   02  null     
      3   03  0    
      

      【讨论】:

        【解决方案4】:

        这是我使用 Analytics 360 测试数据集在 Big Query 上运行的查询:

        select 
        id,
        visitnumber,
        countif(hit_number < hitnumber_quickviewclick) as hitsprev_quickviewclick
        from (
              select 
              a.fullVisitorID as id,
              a.visitnumber as visitnumber,
              h.hitNumber as hit_number,
              MIN (case when h.eventInfo.eventAction = 'Quickview Click' then h.hitNumber end) over (partition by a.fullVisitorID) as hitnumber_quickviewclick
              FROM `bigquery-public-data.google_analytics_sample.ga_sessions_20170725` as a
              CROSS JOIN UNNEST(hits) as h
             ) as T
        group by 1,2;
        

        我想进行一个查询,在该查询中可以找到在事件操作“快速查看点击”被点击之前的点击总数。如果这是错误的或可以改进的,请告诉我!

        非常感谢,伙计们!

        【讨论】:

          【解决方案5】:

          这就是我在 SQL 中的一般处理方式:

          select count(*)
          from yourtable yt
          where type = 'visit' and not exists (
              select 1
              from yourtable yt2
              where yt.id > yt2.id and yt2.type = 'shop'
          )
          

          但是,当我们想在下一家商店...和下​​一家商店...和下​​一家商店之前找到访问时,我会非常考虑这种情况。为此,您可以按时间间隔找出 shop 和 group 的 id。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2020-10-08
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-11-21
            相关资源
            最近更新 更多