django orm中利用annotate進行group by

來源:互聯網
上載者:User

用法

之前的orm的group by方法在django 1.8 中已經不能使用,需要利用annotate來實現

樣本1

第一個values用來選中需要用來group by的欄位(此處group by user_id),之後緊跟annotate來分組並彙總需要的欄位(需要每個user_id對應的question_id的數量和catalog_id的最小值),之後再values來實際查詢需要的欄位(原user_id和彙總後的欄位的別名)

第一個values用來指定用來group by的欄位,裡面必須是Count、Min等等彙總函式(例如用F("user_id")取別名是不行的),不需要最終查詢的就不必彙總了

第二個values用來指定實際select的欄位,只能指定annotate後的欄位名(以此處為例:user_id是用來分組的欄位,可以直接取,而其他欄位必須彙總並使用彙總後的別名,qid和cid,假如原表還有個欄位status,annotate中沒有彙總此欄位,所以最後value不能查詢該欄位)

q = PxbNCEUserQuest.objects.filter(user_id=335).values("user_id").annotate(qid=Min("question_id"), cid=Min("catalog_id")).values("user_id", "qid", "cid")print qprint q.query# 輸出[{'qid': 22, 'user_id': 335L, 'cid': 17}]SELECT `pxb_nce_user_quest`.`user_id`, MIN(`pxb_nce_user_quest`.`question_id`) AS `qid`, MIN(`pxb_nce_user_quest`.`catalog_id`) AS `cid` FROM `pxb_nce_user_quest` WHERE `pxb_nce_user_quest`.`user_id` = 335 GROUP BY `pxb_nce_user_quest`.`user_id` ORDER BY NULL

樣本2

與樣本1一樣,但是此處第一個annotate用來分組欄位,第二個annotate用來單獨別名其他欄位

q = PxbNCEUserQuest.objects.filter(user_id=335).values("user_id").annotate(qid=Min("question_id"), cid=Min("catalog_id")).annotate(uid=F("user_id")).values("uid", "qid", "cid")print qprint q.query# 輸出:[{'qid': 22, 'uid': 335L, 'cid': 17}]SELECT MIN(`pxb_nce_user_quest`.`question_id`) AS `qid`, MIN(`pxb_nce_user_quest`.`catalog_id`) AS `cid`, `pxb_nce_user_quest`.`user_id` AS `uid` FROM `pxb_nce_user_quest` WHERE `pxb_nce_user_quest`.`user_id` = 335 GROUP BY `pxb_nce_user_quest`.`user_id` ORDER BY NULL

舉例:

SomeModel.objects.annotate(Count('somecol'))

GROUP BY: 所有欄位

SomeModel.objects.values('name').annotate(Count('somecol'))

GROUP BY: name欄位,彙總somecol

SomeModel.objects.annotate(Count('somecol')).values('name')

GROUP BY: 所有欄位,查詢name

SomeModel.objects.values('name', 'pk').annotate(Count('somecol')).values('pk')

GROUP BY: name, pk欄位,查詢pk欄位

SomeModel.objects.values('name').annotate(Count('somecol')).values('pk')

GROUP BY: name, pk欄位,查詢pk欄位

關聯知識:

剛開始上面的查詢方法可能比較難理,但是對比原生sql語句的group by方法就會發現類似原理

老版本mysql中

select a, b from t group by a會正常工作,b欄位會自動取第一條,等於是隱式彙總了

新版本mysql中以上語句不能工作,因為預設啟用strict 模式sql_mode=ONLY_FULL_GROUP_BY,正確方法是:

select a,max(b) as b from t group by,即需要顯示的彙總所有查詢的欄位

對比新版mysql文法會發現跟orm中查詢方法很類似

  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.