我正在試圖計算每個月沒有出現在上個月的唯一用戶。所以如果用戶有1月份的記錄,2月份的記錄是2月份的記錄,那麼我只計算該用戶的1月份。如何計算一個月內未出現在前一個月的用戶?
user_id time
a1 1/2/17
a1 2/10/17
a2 2/18/17
a4 2/5/17
a5 3/25/17
我的結果應該是這樣的
Month User Count
January 1
February 2
March 1
我正在試圖計算每個月沒有出現在上個月的唯一用戶。所以如果用戶有1月份的記錄,2月份的記錄是2月份的記錄,那麼我只計算該用戶的1月份。如何計算一個月內未出現在前一個月的用戶?
user_id time
a1 1/2/17
a1 2/10/17
a2 2/18/17
a4 2/5/17
a5 3/25/17
我的結果應該是這樣的
Month User Count
January 1
February 2
March 1
用戶ID和每月第一聚集。然後使用lag()
,看看用戶是否存在於前一個月:
with du as (
select date_trunc(time, month) as yyyymm, user_id
from t
group by date_trunc(time, month)
)
select yyyymm, count(*)
from (select du.*,
lag(yyyymm) over (partition by user_id order by yyyymm) as prev_yyyymm
from du
) du
where prev_yyyymm is not null or
prev_yyyymm < date_add(yyyymm, interval 1 month)
group by yyyymm;
注:本品採用date
功能,但對於timestamp
存在類似的功能。
我理解問題的方式是 - 僅當用戶在前一個月出現過的情況下,才排除用戶在給定月份進行計數。但是,如果同一用戶在給定之前的幾個月內出席,但以前沒有 - 用戶應計算在內。
如果這是正確的 - 下面嘗試使用BigQuery的標準SQL
#standardSQL
SELECT Year, Month, COUNT(DISTINCT user_id) AS User_Count
FROM (
SELECT *,
DATE_DIFF(time, LAG(time) OVER(PARTITION BY user_id ORDER BY time), MONTH) AS flag
FROM (
SELECT
user_id,
DATE_TRUNC(PARSE_DATE('%x', time), MONTH) AS time,
EXTRACT(YEAR FROM PARSE_DATE('%x', time)) AS Year,
FORMAT_DATE('%B', PARSE_DATE('%x', time)) AS Month
FROM yourTable
GROUP BY 1, 2, 3, 4
)
)
WHERE IFNULL(flag, 0) <> 1
GROUP BY Year, Month, time
ORDER BY time
您可以測試/上面使用例如虛擬數據低於從你的問題
#standardSQL
WITH yourTable AS (
SELECT 'a1' AS user_id, '1/2/17' AS time UNION ALL
SELECT 'a1', '2/10/17' UNION ALL
SELECT 'a2', '2/18/17' UNION ALL
SELECT 'a4', '2/5/17' UNION ALL
SELECT 'a5', '3/25/17'
)
SELECT Year, Month, COUNT(DISTINCT user_id) AS User_Count
FROM (
SELECT *,
DATE_DIFF(time, LAG(time) OVER(PARTITION BY user_id ORDER BY time), MONTH) AS flag
FROM (
SELECT
user_id,
DATE_TRUNC(PARSE_DATE('%x', time), MONTH) AS time,
EXTRACT(YEAR FROM PARSE_DATE('%x', time)) AS Year,
FORMAT_DATE('%B', PARSE_DATE('%x', time)) AS Month
FROM yourTable
GROUP BY 1, 2, 3, 4
)
)
WHERE IFNULL(flag, 0) <> 1
GROUP BY Year, Month, time
ORDER BY time
輸出是玩
Year Month User_Count
2017 January 1
2017 February 2
2017 March 1
我不認爲這是OP想要的。基本上希望在第一次出現在一個月內計算用戶,並且不再計算一次。 – CodingYoshi
在下面的語句'上個月沒有出現''''單注'月份'。不是'月',而是'月'。無論如何 - 讓我們把它留給OP來澄清! :o) –
同意讓我們這樣做。不知道爲什麼我提供我的2美分,甚至不富裕;) – CodingYoshi
我不是真的家人用BigQuery騙子,但這裏是我如何使用TSQL解決問題。我想你可以在BigQuery中使用類似的邏輯。
1)。先按user_id排序,然後按時間排序。在TSQL中,可以使用以下代碼完成此操作,並將其存儲在公用表表達式中,然後在此步驟中查詢。
;WITH cte AS
(
select ROW_NUMBER() OVER (PARTITION BY [user_id] ORDER BY [time]) AS rn,*
from dbo.employees
)
2)。接下來只查詢rn = 1的行(特定用戶的第一次出現)和月份的組。
select DATENAME(month, [time]) AS [Month], count(*) AS user_count
from cte
where rn = 1
group by DATENAME(month, [time])
這是假設2017年是你處理的唯一一年。如果您正在處理超過一年,你可能想步驟#2是這個樣子:
select year([time]) as [year], DATENAME(month, [time]) AS [month],
count(*) AS user_count
from cte
where rn = 1
group by year([time]), DATENAME(month, [time])
「所以,如果一個用戶有一月二月的紀錄,然後又一個,那麼我只會計算該用戶的一月份。「你的意思是你只計算二月? – CodingYoshi
他只想算第一次...... – Teja