2017-03-08 60 views
0

我们有一个用Django编写的系统来跟踪招募到临床试验的患者。 传播表格用于记录整个财政年度每月招募的患者人数;所以该表只包含12个月的数据,尽管研究可能会运行多年。在Django ORM中选择最近的行与分组

django数据库中有一张表,每个月都会导入电子表格。数据包括月/年,患者数量和其他一些领域。每次导入都将包含以前的所有月份数据;我们需要这样做,以确保自上次导入后,导入表单上没有数据更改。

例如,包含两个进口(第一长达一月的第二到二月)导入表是这样的:

id | study_id | data_date | patient_count | [other fields] --> 
100  5456 2016-04-01    10  ... 
101  5456 2016-05-01    8  ... 
102  5456 2016-06-01    5  ... 
    ... all months in between ... 
109  5456 2016-01-01    12  ... 
110  5456 2016-02-01   NULL  ... 
111  5456 2016-03-01   NULL  ... 
112  5456 2016-04-01    10  ... 
113  5456 2016-05-01    8  ... 
114  5456 2016-06-01    5  ... 
    ... all months in between ... 
121  5456 2016-01-01    12  ... 
122  5456 2016-02-01    6  ... 
123  5456 2016-03-01   NULL  ... 

其他领域包括一个外键包含另一个表实际学习识别号码(iras_number),所以我必须加入到选择特定研究的行中。

我想最近的data_datepatient_count的研究价值,可能跨越一个以上的财政年度,所以我想这个查询(iras_number被传递给函数执行此查询):

totals = ImportStudyData.objects.values('data_date', 'patient_count') \ 
     .filter(import_study__iras_number=iras_number) \ 
     .annotate(max_id=Max('id')).order_by() 

然而,这将产生一个SQL查询,其中包括patient_countGROUP BY,导致重复行:

data_date | patient_count | max_id 
2016-04-01    10  100 
2016-04-01    10  112 
2016-05-01    8  101 
2016-05-01    8  113 
    ... 
2016-01-01    12  109 
2016-01-01    12  121 
2016-02-01   NULL  110 
2016-02-01    6  122 

如何选择最近data_datepatient_count从表中使用ORM?

如果我写的SQL,我会做一个内部的选择了max(id)data_date分组,然后用它来加入,或使用IN查询,选择我从表中要求的领域;如:

SELECT data_date, patient_count 
FROM importstudydata 
WHERE id IN (
    SELECT MAX(id) AS "max_id" 
    FROM importstudydata INNER JOIN importstudy 
     ON importstudydata.import_study_id = importstudy.id 
    WHERE importstudy.iras_number = 5456 
    GROUP BY importstudydata.data_date 
) 
ORDER BY data_date ASC 

我试图创建一个内选择要复制的SQL查询,但内部的选择返回多个字段(列)一个导致查询失败:

totals = ImportStudyData.objects.values('data_date', 'patient_count') \ 
     .filter(id__in=ImportStudyData.objects.values('data_date') \ 
         .filter(import_study__iras_number=iras_number) \ 
         .annotate(max_data_id=Max('id')) 

现在我无法获得内部选择,只返回按'data_date'分组的max(id),并且它将在单个SQL查询中执行。

回答

0

现在我将查询到的多个步骤来获得我想要的结果。

首先,我查询了最近有关研究

id_qry = ImportStudyData.objects.values('data_date')\ 
    .filter(import_study__iras_number=iras_number)\ 
    .annotate(max_id=Max('id')) 

得到公正的号码列表,剥出日期的所有行id,我使用列表理解:

id_list = [x['max_id'] for x in id_qry] 

此列表,然后用作过滤器的最终查询来获取患者的数量

totals = ImportStudyData.objects.values('data_date', 'patient_count') \ 
     .filter(id__in=id_list) 

它击中数据库两次,计算更昂贵,但现在它工作,我需要继续前进。

我稍后会回到这个问题。

-1

使用:不同的=真

totals = ImportStudyData.objects.values('data_date', 'patient_count').filter(import_study__iras_number=iras_number).annotate(max_id=Max('id')).order_by('data_date').distinct() 
+0

当我添加'明显= TRUE'的注释调用我得到的错误里面'“布尔”对象有没有属性“resolve_expression''。 'distinct'参数是否需要成为'max'函数参数的一部分? – Tony

+0

将'distinct'移动到查询字符串的末尾意味着它将执行到SQL语句,但它仍然会返回重复项,因为'distinct'应用于所有字段('data_date','patient_count'和'max_id' )已经不同了。 – Tony