我有一个问题,在练习SQL技能时无法完全弄清楚,希望在这里能有所启发。
基于带有数据行的表模式,如下所示:
click_datetime | click_day | customer_id | page_id
6/5/2016 0:31 6/5/2016 1111 ABCDE
我想获取每个客户最近一天访问的第一个page_id。
棘手的部分是,我需要先找到每个客户的click_day的最大值,然后再找到每个客户的click_datetime的最小值,然后再选择page_id。
到目前为止,这是我所拥有的:
SELECT customer_id, MAX(click_day), page_id
FROM
(SELECT customer_id, click_day, page_id, MIN(click_datetime) FROM Clickdata
GROUP BY customer_id, click_day, page_id) Clickdata
WHERE page_id != ''
GROUP BY customer_id, page_id
您可以在此处找到SQL Fiddle:http://sqlfiddle.com/#!17/8cabb/29
到目前为止,我似乎还不太能获得最终输出,该输出仅应向我显示每个客户的一个page_id值以及相应的最后一天访问。但是不知何故,我仍然得到多行。
有人可以指出我在这里做错了什么吗?谢谢!
答案 0 :(得分:0)
尝试一下:
select
*
from
( select
*,
row_number() over( partition by
customer_id
order by
to_date(click_day, 'dd/mm/yyyy') desc, -- use click_day without conversion if it is of type "date"
click_datetime) as rn
from
Clickdata) as x
where
rn = 1
答案 1 :(得分:0)
您可以使用NOT EXISTS和CTE来做到这一点:
with cte as (
select c.* from clickdata c
where not exists (
select 1 from clickdata
where customer_id = c.customer_id and click_day > c.click_day
)
)
select c.* from cte c
where not exists (
select 1 from cte
where customer_id = c.customer_id and click_datetime < c.click_datetime
)
请参见demo。
结果:
> click_datetime | click_day | customer_id | page_id
> :------------------ | :--------- | ----------: | :---------
> 2017-04-12 03:23:00 | 2017-04-12 | 1111 | B00T8HT71Y
> 2017-06-22 17:40:00 | 2017-06-22 | 2222 | B000VZPW5W