在Django中进行筛选的Creage聚合查询

时间:2019-08-14 17:48:26

标签: django django-orm

我有下表/模型。我试图弄清楚如何将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')
        )

0 个答案:

没有答案
相关问题