Sql 谷歌大查询排名顺序与客户点击问题
我正在使用google big query跟踪一些客户对我网站的点击。我遵循一个简单的规则集:Sql 谷歌大查询排名顺序与客户点击问题,sql,google-bigquery,ranking,Sql,Google Bigquery,Ranking,我正在使用google big query跟踪一些客户对我网站的点击。我遵循一个简单的规则集: 如果客户在同一天连续多次通过同一来源,我只想看到第一个命中来源 我只想看到第一个击中来源,如果客户已经通过同一来源多次连续在不同的日子 我希望看到所有命中源,如果它们出现在同一天,但不是连续出现 目前,我正在使用以下工具: rank() over (partition by customer_code, hit_source order by hit_timedate) rnk 如果我在“wh
rank() over (partition by customer_code, hit_source order by hit_timedate) rnk
如果我在“where rnk=1”上过滤,这允许我完成前两个步骤。这只会给我不同的命中源,无论它们是否在同一天,因为我有一个在命中时间内的时间。但它并没有给我第三步,因为排名是由hit_源划分的,当它看到相同的源时会改变
如果有人能在这方面帮助我,我将不胜感激
编辑:
不确定如何添加/上载示例数据集,因此我尝试在此处执行此操作:
Customer_Code Hit_Source Hit_Timedate
101 Facebook 25/05/2020 10:30am
101 Facebook 25/05/2020 11:45am
101 Facebook 25/05/2020 11:55am
101 Twitter 25/05/2020 12:30am
101 Facebook 25/05/2020 13:00pm
101 Google 25/05/2020 15:00pm
101 Instagram 26/05/2020 09:00am
理想情况下,理想的结果集如下:
Customer_Code Hit_Source Hit_Timedate Rank
101 Facebook 25/05/2020 10:30am 1
101 Facebook 25/05/2020 11:45am 2
101 Facebook 25/05/2020 11:55am 3
101 Twitter 25/05/2020 12:30am 1
101 Facebook 25/05/2020 13:00pm 1
101 Google 25/05/2020 15:00pm 1
101 Instagram 26/05/2020 09:00am 1
因此,根据我的规则,我想实施上述。。我在这里遇到的主要问题是,能否将样本中的第5行排序为“1”。我之所以这么做,是因为最近两次“Facebook”的点击不是连续的。但要用我实现的前两条规则做到这一点,我很难做到。您可以使用lag()
和累积计数:
select t.*,
1 + countif(prev_source = source) over (partition by customer_code, datetime_trunc(hit_timedate, day) order by hit_timedate) as ranking
from (select t.*,
lag(source) over (partition by customer_code, datetime_trunc(hit_timedate, day)
order by hit_timedate
) as prev_source
from t
) t;
其思想是创建一个标志,表明前一个源是否与当前行相同——如果不相同,则添加1。
1+
是因为计数将从0
开始,您希望计数从1
开始,以便进一步为社区做出贡献,我将使用不同的方法与BigQuery的内置函数共享
下面是代码,使用您提供的示例数据分为2个步骤(在中进行了注释):
with data as (
SELECT 101 as Customer_Code,"Facebook" as Hit_Source ,DATETIME(2020,05,25,10,30,00) as Hit_Timedate UNION ALL
SELECT 101 as Customer_Code,"Facebook" as Hit_Source ,DATETIME(2020,05,25,11,45,0) as Hit_Timedate UNION ALL
SELECT 101 as Customer_Code,"Facebook" as Hit_Source ,DATETIME(2020,05,25,11,55,0) as Hit_Timedate UNION ALL
SELECT 101 as Customer_Code,"Twitter" as Hit_Source ,DATETIME(2020,05,25,12,30,0) as Hit_Timedate UNION ALL
SELECT 101 as Customer_Code,"Facebook" as Hit_Source ,DATETIME(2020,05,25,13,00,0) as Hit_Timedate UNION ALL
SELECT 101 as Customer_Code,"Google" as Hit_Source ,DATETIME(2020,05,25,15,00,0) as Hit_Timedate UNION ALL
SELECT 101 as Customer_Code,"Instagram" as Hit_Source ,DATETIME(2020,05,25,09,00,0) as Hit_Timedate
),
#step 1
data1 as (
SELECT Customer_Code, Hit_Source, Hit_Timedate, LAG(Hit_Source,1) OVER (ORDER BY Hit_Timedate) as PrevHit from data
),
#step 2
data2 as (
SELECT Customer_Code, Hit_Source,PrevHit , Hit_Timedate, SUM(CASE WHEN Hit_Source = PrevHit THEN 0 ELSE 1 END) OVER (ORDER BY Hit_Timedate,Hit_Source) AS rank_aux
FROM data1
)
SELECT Customer_Code, Hit_Source, MIN(Hit_Timedate) AS first_Hit_Timedate, RANK() OVER (PARTITION BY rank_aux order by Hit_Timedate) as rank FROM data2
GROUP BY Customer_Code, Hit_Source, rank_aux,Hit_Timedate
ORDER BY Customer_Code,first_Hit_Timedate, Hit_Source
和最终输出,
请注意,在步骤1中,将创建一个新列,其中包含Hit_Source
的先前值。然后在步骤2中,创建一个新列rank_aux
,以便正确聚合结果。以下是步骤2的输出(仅用于解释):
注意第二、第三和第四行,其中的
rank_aux=2
,这是所需的输出,因此可以将这些列聚合为1,并仅显示最小的Hit_Timedate
,以获得已共享的最终输出。请提供示例数据和所需结果。正如@GordonLinoff所说,你能分享一下样本数据和预期结果吗?所以,最好创建一个查询并对其进行测试。您好,示例和所需结果集作为一个版本添加到我的原始帖子中。谢谢。@DB1993,为什么Facebook在2020年5月25日13:00pm排名1而不是4?你好,Alexandre,这是因为Facebook的第4行不是连续的,因为之前有不同的点击源,所以它会重置回排名1,这是我计划实现的逻辑。我希望你能理解您好,根据我的原始问题,这与我期望的结果集不匹配。请特别注意所需的结果集“排名”。Facebook的第一个和第四个实例应该是排名1,因为之前的热门来源不是Facebook。@db1993,您好,谢谢您让我知道。因此,我们的想法是,在我们有了一个允许我们对连续动作进行分组的专栏之后,就有可能进行排名。因此,您只需在代码的最后一部分中使用RANK()函数。我已经上传了新的代码和输出。你检查过了吗?请考虑投票和接受答案。@ DbBDB1993,请考虑接受和投票的答案。您好,使用亚历山大的例子,他的CTE手动插入数据集。这似乎给了我每行3的排名。我需要有我在期望的结果集中指定的排名。这样我就可以过滤排名=1的位置等@db1993。countif()
需要一个orderby
子句。
Row Customer_Code Hit_Source first_Hit_Timedate rank
1 101 Instagram 2020-05-25T09:00:00 1
2 101 Facebook 2020-05-25T10:30:00 1
3 101 Facebook 2020-05-25T11:45:00 2
4 101 Facebook 2020-05-25T11:55:00 3
5 101 Twitter 2020-05-25T12:30:00 1
6 101 Facebook 2020-05-25T13:00:00 1
7 101 Google 2020-05-25T15:00:00 1
Row Customer_Code Hit_Source PrevHit Hit_Timedate rank_aux
1 101 Instagram null 2020-05-25T09:00:00 1
2 101 Facebook Instagram 2020-05-25T10:30:00 2
3 101 Facebook Facebook 2020-05-25T11:45:00 2
4 101 Facebook Facebook 2020-05-25T11:55:00 2
5 101 Twitter Facebook 2020-05-25T12:30:00 3
6 101 Facebook Twitter 2020-05-25T13:00:00 4
7 101 Google Facebook 2020-05-25T15:00:00 5