這裏主要介紹一下,在一張數據表下對相鄰的數據進行一個相關查詢和計算;
拿一個在電商中最常見的情況,計算一下用戶首單和第二單的時間間隔這樣的數據來舉例,如下:
id | customer_id | created_at |
---|---|---|
1 | 1 | 2017-07-21 09:43:02 |
2 | 12 | 2017-07-25 11:37:48 |
3 | 10 | 2017-07-25 11:43:41 |
4 | 1 | 2017-07-27 01:27:22 |
5 | 10 | 2017-07-27 07:46:45 |
6 | 1 | 2017-07-27 10:21:37 |
7 | 12 | 2017-07-27 13:26:19 |
查詢用戶首單和第二單的時間間隔:
SELECT
m.customer_id,
sfo.created_at as '首單時間',
m.created_at as '第二單時間',
(unix_timestamp(m.created_at) - unix_timestamp(sfo.created_at))/86400 as '兩單相差天數'
FROM
sales_flat_order m
LEFT JOIN
sales_flat_order sfo on m.customer_id = sfo.customer_id and sfo.created_at < m.created_at
WHERE
(
SELECT
count(*)
FROM
sales_flat_order n
WHERE
m.customer_id = n.customer_id
AND m.created_at > n.created_at
) = 1
GROUP BY m.customer_id
查詢結果是:
customer_id | 首單時間 | 第二單時間 | 兩單時間差 |
---|---|---|---|
1 | 2017-07-21 09:43:02 | 2017-07-27 01:27:22 | 5.6558 |
12 | 2017-07-25 11:37:48 | 2017-07-27 13:26:19 | 2.0754 |
10 | 2017-07-25 11:43:41 | 2017-07-27 07:46:45 | 1.8355 |
整個原理如下:
- 將一張表查詢兩次得到兩組數據,分別爲別名m和別名n的兩組數據;
- 以m爲主,用n的數據和m的數據作對比,通過created_at的判斷過濾掉一些無用數據;
- 使用count()函數統計滿足條件的數據個數;
- 統計數爲1時說明n表中比m表中時間小的只有1條,m中的該條數據也就是該用戶下的第二筆訂單;
- 通過LEFT JOIN聯表,通過created_at找到比第二單更早的一單也就是用戶的首單;
- 利用unix_timestamp把得到的兩條數據的created_at做差,得到了兩筆訂單的時間間隔;
下面做了一下拓展,可以查詢任意相連的兩筆訂單的時間間隔:
SELECT
m.customer_id,
m.created_at as '後一單時間',
SUBSTRING_INDEX(
GROUP_CONCAT(sfo.created_at ORDER BY sfo.created_at DESC),
',',
1
) as '前一單時間',
(unix_timestamp(m.created_at) - unix_timestamp(
SUBSTRING_INDEX(
GROUP_CONCAT(sfo.created_at ORDER BY sfo.created_at DESC),
',',
1
)
))/86400 as '兩單相差天數'
FROM
sales_flat_order m
LEFT JOIN
sales_flat_order sfo on m.customer_id = sfo.customer_id and sfo.created_at < m.created_at
WHERE
(
SELECT
count(*)
FROM
sales_flat_order n
WHERE
m.customer_id = n.customer_id
AND m.created_at > n.created_at
) = 2
GROUP BY m.customer_id;
得到數據如下:
customer_id | 後一單時間 | 前一單時間 | 兩單時間差 |
---|---|---|---|
1 | 2017-07-27 10:21:37 | 2017-07-27 01:27:22 | 0.3710 |
這裏判斷的是統計數爲2的,也就是用戶的第二單和第三單的時間間隔計算,因爲用戶10和12只有兩單所以結果中無這兩個用戶;
整個原理如下:
- 將一張表查詢兩次得到兩組數據,分別爲別名m和別名n的兩組數據;
- 以m爲主,用n的數據和m的數據作對比,通過created_at的判斷過濾掉一些無用數據;
- 使用count()函數統計滿足條件的數據個數;
- 篩選之後m中得到的是第三筆訂單;
- 通過LEFT JOIN聯表,通過created_at找到比第三筆訂單時間早的訂單,這裏會從sfo中得到兩筆訂單;
- 利用GROUP_CONCAT函數每組訂單中各得到的兩筆訂單利用created_at進行降序排序,然後得到通過‘,’連接的兩條數據的時間,如下:
2017-07-27 01:27:22,2017-07-21 09:43:02
- 使用SUBSTRING_INDEX函數通過’,'將數據拆分再拿到第一條數據,也就是第二筆訂單的時間了;
- 利用unix_timestamp對created_at作差,得到兩筆訂單的時間間隔;
這只是我想到的應對這種場景通過SQL語句進行查詢的方法,如果有小夥伴有更好的方法或者改進的方法,歡迎小夥伴留言,謝謝啦!