想象一下企业与人们的互动表:
+-----------+---------------------+-----------------+
| user_name | action_timestamp | action |
+-----------+---------------------+-----------------+
| john | 2017-01-01 10:00:00 | phone_call |
+-----------+---------------------+-----------------+
| john | 2017-01-02 12:00:00 | became_customer |
+-----------+---------------------+-----------------+
| john | 2017-01-03 14:00:00 | phone_call |
+-----------+---------------------+-----------------+
| jane | 2016-08-06 10:00:00 | phone_call |
+-----------+---------------------+-----------------+
| jane | 2016-08-06 11:00:00 | phone_call |
+-----------+---------------------+-----------------+
| jane | 2016-08-06 12:00:00 | became_customer |
+-----------+---------------------+-----------------+
| tony | 2016-12-01 15:00:00 | phone_call |
+-----------+---------------------+-----------------+
我想要达到这样的目的:
+-----------+---------------+-------------+---------------------+------------------------------+-----------------------------+
| user_name | total_actions | is_customer | became_customer | interactions_before_customer | interactions_after_customer |
+-----------+---------------+-------------+---------------------+------------------------------+-----------------------------+
| john | 3 | TRUE | 2017-01-02 12:00:00 | 1 | 1 |
+-----------+---------------+-------------+---------------------+------------------------------+-----------------------------+
| jane | 3 | TRUE | 2016-08-06 12:00:00 | 2 | 0 |
+-----------+---------------+-------------+---------------------+------------------------------+-----------------------------+
| tony | 1 | FALSE | NULL | 1 | 0 |
+-----------+---------------+-------------+---------------------+------------------------------+-----------------------------+
前4列对于一些分组和CASE是微不足道的,但我不知道如何进行第5列和第6列(客户之间的交互以及客户之后的交互),因为案例是基于先前的结果列,并且需要在行之间变化。
这比它看起来更简单吗?如果有人关心我不在呼叫中心工作,它只是一个比我试图做的更简单的类比;)
答案 0 :(得分:2)
这会给你一个想法。我已在ORACLE
上对此进行了测试,但它运行正常,
WITH CUS_DET AS (
SELECT *
FROM INTERACTIONS
WHERE ACTION = 'became_customer'
)
SELECT INTERACTIONS.USER_NAME
, SUM(CASE
WHEN (CUS_DET.ACTION_TIMESTAMP IS NULL
OR INTERACTIONS.ACTION_TIMESTAMP < CUS_DET.ACTION_TIMESTAMP)
THEN 1
ELSE 0
END) BEF
, SUM(CASE
WHEN INTERACTIONS.ACTION_TIMESTAMP > CUS_DET.ACTION_TIMESTAMP
THEN 1
ELSE 0
END) AFT
FROM INTERACTIONS
LEFT OUTER JOIN CUS_DET
ON INTERACTIONS.USER_NAME = CUS_DET.USER_NAME
GROUP BY INTERACTIONS.USER_NAME;
答案 1 :(得分:2)
如果用户只能成为客户一次,则使用条件聚合:
select
t.user_name
, case when c.action_timestamp is not null then 'Yes' else 'No' end as Is_Customer
, c.action_timestamp as became_customer
, count(case when t.action_timestamp < coalesce(c.action_timestamp,'2525-01-01') then 1 end) as interactions_before_customer
, count(case when t.action_timestamp > c.action_timestamp then 1 end) as interactions_after_customer
from t
left join t as c
on t.user_name = c.user_name
and c.action = 'became_customer'
group by t.user_name, c.action_timestamp
rextester演示:http://rextester.com/LOUGN53032
+-----------+-------------+---------------------+------------------------------+-----------------------------+
| user_name | Is_Customer | became_customer | interactions_before_customer | interactions_after_customer |
+-----------+-------------+---------------------+------------------------------+-----------------------------+
| tony | No | NULL | 1 | 0 |
| jane | Yes | 2016-08-06 12:00:00 | 2 | 0 |
| john | Yes | 2017-01-02 12:00:00 | 1 | 1 |
+-----------+-------------+---------------------+------------------------------+-----------------------------+