2017-03-08 57 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