我有下表/模型。我试图弄清楚如何将SQL查询转换为Django 1.11语法。特别是,我很难在Django的When中添加其他过滤器参数。 http://sqlfiddle.com/#!9/8c6974/26 这是SQL的创建/填充:
create table Activity (
Id INT AUTO_INCREMENT,
username varchar(50),
course_id varchar(50),
activity_type varchar(50),
activity_action varchar(50),
times INT,
date_event DATETIME,
PRIMARY KEY(id)
);
INSERT INTO Activity
(username, course_id, activity_type, activity_action, times, date_event)
VALUES
( 'john', '123', 'video', 'viewed', 2, str_to_date('01-08-2019', '%d-%m-%Y')),
( 'john', '123', 'problem', 'attempted', 11, str_to_date('02-08-2019', '%d-%m-%Y')),
( 'john', '123', 'problem', 'attempted', 22, str_to_date('03-08-2019', '%d-%m-%Y')),
( 'john', '123', 'problem', 'attempted', 33, str_to_date('02-07-2019', '%d-%m-%Y')),
( 'john', '123', 'problem', 'solved', 4, str_to_date('01-08-2019', '%d-%m-%Y')),
( 'john', '123', 'problem', 'solved', 5, str_to_date('01-01-2019', '%d-%m-%Y')),
( 'john', '123', 'problem', 'solved', 6, str_to_date('01-02-2019', '%d-%m-%Y')),
( 'adam', '123', 'video', 'viewed', 2, str_to_date('01-08-2019', '%d-%m-%Y')),
( 'adam', '123', 'problem', 'attempted', 11, str_to_date('02-08-2019', '%d-%m-%Y')),
( 'adam', '123', 'problem', 'attempted', 22, str_to_date('03-08-2019', '%d-%m-%Y')),
( 'adam', '123', 'problem', 'attempted', 33, str_to_date('02-07-2019', '%d-%m-%Y')),
( 'adam', '123', 'problem', 'solved', 4, str_to_date('01-08-2019', '%d-%m-%Y')),
( 'adam', '123', 'problem', 'solved', 5, str_to_date('01-01-2019', '%d-%m-%Y')),
( 'adam', '123', 'problem', 'solved', 6, str_to_date('01-02-2019', '%d-%m-%Y')),
( 'meg', '123', 'discussion', 'asked', 6, str_to_date('03-02-2019', '%d-%m-%Y')),
( 'meg', '123', 'discussion', 'asked', 6, str_to_date('03-02-2019', '%d-%m-%Y'))
;
我的SQL查询:
select
username,
sum(case when activity_type = 'video' and activity_action = 'viewed' then times else 0 end) as times_viewed_video_overall,
sum(case when activity_type = 'video' and activity_action = 'viewed' and date(date_event) >= date_sub(current_date(), interval 7 day) then times else 0 end) as times_viewed_video_lw,
sum(case when activity_type = 'problem' and activity_action = 'attempted' then times else 0 end) as times_attempted_problem_overall,
sum(case when activity_type = 'problem' and activity_action = 'attempted' and date(date_event) >= date_sub(current_date(), interval 7 day) then times else 0 end) as times_attempted_problem_lw,
max(date_event) as last_activity
from
Activity
where course_id='123'
group by
username
,course_id;
我在Django查询中的尝试: 注意:上周是我要计算的。总体看来可行。
def get_aggregate_engagement_data(self, course_id):
seven_days_ago = datetime.today() - timedelta(days=7)
mq = Q(entity_type='video')
objs = ModuleEngagement.objects.filter(course_id=course_id) \
.values('username') \
.annotate(
times_video_viewed_overall=Sum(Case(When(activity_type='video', then=1),
output_field=IntegerField()))) \
.annotate(
times_video_viewed_last_week=Sum(Case(When(activity_type='video', then=1), output_field=IntegerField()))) \
.annotate(
times_attempted_problem_overall=Sum(Case(When(activity_type='problem', then=1),
output_field=IntegerField()))) \
.annotate(
times_attempted_problem_last_week=Sum(Case(When(activity_type='problem', then=1),
output_field=IntegerField()))) \
.annotate(
date_last_active=Max('created')
)