2017-03-08 11 views
0

Djangoで書かれたシステムでは、臨床試験に募集した患者を追跡しています。 スプレッドシートは、会計年度を通じて毎月募集された患者の数を記録するために使用されます。研究は何年も実行されているにもかかわらず、シートには12ヶ月のデータしか含まれていません。グループ化されたDjango ORMの最新の行を選択

毎月スプレッドシートをインポートするテーブルがDjangoデータベースにあります。データには、月/年、患者数、その他のフィールドが含まれます。各インポートには、前の月のデータがすべて含まれます。最後にインポートしてからインポート・シート上のデータが変更されていないことを確認するために必要です。

例えば、2つの輸入(1月と2月に第2のアップまでの最初の)を含むインポートテーブルは次のようになります。

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)ですので、特定のスタディの行を選択するためにそれに参加しなければなりません。

totals = ImportStudyData.objects.values('data_date', 'patient_count') \ 
     .filter(import_study__iras_number=iras_number) \ 
     .annotate(max_id=Max('id')).order_by() 
:( iras_numberこのクエリを実行する関数に渡されます)

は、私には、複数の会計年度にまたがることがありdata_dateと研究のためpatient_countの最新の値を、したいので、私はこのクエリを試してみました

しかし、これは重複行で、その結果、GROUP BYpatient_countを含んでSQLクエリを生成します。

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 

私は最新を選択するにはどうすればよいですとpatient_countは、ORM?

私はdata_dateでグループ化されたmax(id)の内側の選択を行い、その後、参加するためにそれを使用、または私はテーブルから必要なフィールドを選択するには、INクエリを使用するSQLを書いていた場合。以下のような:

私はしかし、内側の選択に戻り、SQLクエリを複製するインナー選択を作成するために、複数のフィールド(列)aは、クエリが失敗する試みた
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 

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) 

データベースを2回ヒットし、計算コストが高くなりますが、今のところ動作しています。

私は後でこの問題に戻ってきます。

-1

用途:明確な= Trueの

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

アノテーション呼び出しの中に 'distinct = True'を追加すると、' 'bool 'オブジェクトに' resolve_expression 'という属性がありません。 'distinct'パラメータは' max'関数パラメータの一部である必要がありますか? – Tony

+0

問合せ文字列の最後に 'distinct'を移動すると、実行されたSQL文に渡されますが、' distinct'がすべてのフィールド( 'data_date'、' patient_count'および 'max_id')に適用されるため、 )は既に異なっている。 – Tony

関連する問題