Я думаю, что один из подходов может заключаться в объявлении переменных, если вы используете скрипт, чтобы вы могли извлекать / отмечать свой вывод для end_date в вашем интервале. Например,
declare end_dt date default "2020-07-05"; -- this can be used as placeholder and replaced at run-time based on execution
declare start_dt date default DATE_SUB(end_dt, INTERVAL 5 DAY);
select
end_dt as ts_date,
id,
sum(CASE WHEN lang = 'EN' THEN 1 ELSE 0 END) AS lang_EN,
sum(CASE WHEN lang = 'SN' THEN 1 ELSE 0 END) AS lang_SN
from(
-- sample data
select cast("2020-07-01 01:01:25.550 UTC" as timestamp) as ts, "A" as id, "EN" as lang
union all
select cast("2020-07-01 01:01:25.550 UTC" as timestamp) as ts, "A" as id, "EN" as lang
union all
select cast("2020-07-01 01:01:25.550 UTC" as timestamp) as ts, "A" as id, "SN" as lang
union all
select cast("2020-07-02 01:01:25.550 UTC" as timestamp) as ts, "B" as id, "EN" as lang
union all
select cast("2020-07-02 01:01:25.550 UTC" as timestamp) as ts, "B" as id, "EN" as lang
union all
select cast("2020-07-02 01:01:25.550 UTC" as timestamp) as ts, "B" as id, "SN" as lang
union all
select cast("2020-07-02 01:01:25.550 UTC" as timestamp) as ts, "B" as id, "SN" as lang
union all
select cast("2020-07-03 01:01:25.550 UTC" as timestamp) as ts, "C" as id, "SN" as lang
union all
select cast("2020-07-03 01:01:25.550 UTC" as timestamp) as ts, "C" as id, "EN" as lang
union all
select cast("2020-07-03 01:01:25.550 UTC" as timestamp) as ts, "D" as id, "SN" as lang
union all
select cast("2020-07-04 01:01:25.550 UTC" as timestamp) as ts, "D" as id, "EN" as lang
) where date(ts) between start_dt and end_dt
group by 1,2
И вывод:
Row ts_date id lang_EN lang_SN
1 2020-07-05 A 2 1
2 2020-07-05 B 2 2
3 2020-07-05 C 1 1
4 2020-07-05 D 1 1