I would like to count the distinct number of emails of the current month and the previous 2 months. Preferably I'd like the syntax to be in PySpark, rather than SQL.
Example input:
df = spark.createDataFrame(
[('2022-01-01', 'A'),
('2022-01-01', 'A'),
('2022-01-01', 'A'),
('2022-01-01', 'B'),
('2022-01-01', 'Z'),
('2022-01-01', 'Z'),
('2022-02-01', 'A'),
('2022-02-01', 'B'),
('2022-02-01', 'C'),
('2022-02-01', 'D'),
('2022-02-01', 'Z'),
('2022-02-01', 'A'),
('2022-02-01', 'F'),
('2022-03-01', 'A'),
('2022-03-01', 'B'),
('2022-03-01', 'B'),
('2022-03-01', 'C'),
('2022-04-01', 'G'),
('2022-04-01', 'H'),
('2022-05-01', 'G'),
('2022-05-01', 'H'),
('2022-05-01', 'I'),
('2022-06-01', 'I'),
('2022-06-01', 'J'),
('2022-06-01', 'K')],
['yyyy_mm_dd', 'email']
)
Desired output:
| yyyy_mm_dd | count_distinct_email |
|---|---|
| 2022-01-01 | 3 |
| 2022-02-01 | 6 |
| 2022-03-01 | 6 |
| 2022-04-01 | 8 |
| 2022-05-01 | 6 |
| 2022-06-01 | 5 |
As rangeBetween doesn't support months, I was forced to use SQL syntax to achieve the rolling distinct count. I tried this
users_base.createOrReplaceTempView('users_base')
users_unique = spark.sql(
'SELECT \
yyyy_mm_dd, \
COUNT(DISTINCT soylent_booker_email_id_orig) OVER ( \
ORDER BY CAST(yyyy_mm_dd AS timestamp) ASC\
RANGE BETWEEN INTERVAL 2 MONTHS PRECEDING AND CURRENT ROW \
) AS users_unique_count \
FROM \
users_base'
)
but it's not workking and I found out that COUNT DISTINCT is not supported for window functions. Does somebody have any idea how I can generate my desired output? Thanks!