【发布时间】:2019-04-20 11:40:14
【问题描述】:
数据模型:
- 每个
Library有很多Books -
UserBookReceipt指定的User可能会或可能不会读取每个Book
目标:
给定一个用户,按照他们在每个图书馆阅读的书籍数量对图书馆进行排序。
示例:
用户 1 已阅读:
- 图书馆 1 中的 2 本书
- 图书馆 2 中的 5 本书
- 图书馆 3 中的 1 本书
- 图书馆 4 中的 0 本书
我们应该按照用户 1 阅读的书籍数量的顺序归还图书馆,即:
Library 2, Library 1, Library 3
当前解决方案
libraries = (UserBookReceipt.objects
.filter(user=user)
.values('book__library')
.annotate(rcount=Count('book__library'))
.order_by('-rcount')
)
实际输出
[
{'book_library': 2, 'rcount': 5},
{'book_library': 1, 'rcount': 2},
{'book_library': 3, 'rcount': 1}
]
预期输出
[
{'book_library': <Library: 2>, 'rcount': 5},
{'book_library': <Library: 1>, 'rcount': 2},
{'book_library': <Library: 3>, 'rcount': 1}
]
实际输出是我想要的 90%,除了我希望 book_library 值是 django Library 模型的实例,而不仅仅是库 id。否则,我必须进行另一个查询来检索 Library 对象,这可能需要一些低效的 ids__in query。
如何按UserBookReceipt.book__library 计数和分组并返回库模型?
如果我在 SQL 中执行此操作,查询将如下所示
with rcount_per_lib as (
select lib.id, count(*) as rcount
from lib, books, user_book_receipts
where user_book_receipts.book_id = books.id
and lib.id = books.lib_id
and user_book_receipts.user_id = 1
group by lib.id)
select lib.*, rcount from rcount_per_lib
where lib.id = rcount_per_lib.id
order by rcount
【问题讨论】:
-
如果你要使用 SQL,你真的应该使用正确、明确、标准
JOIN语法。 -
为什么? AFAIK
and语法在性能方面与INNER JOIN等效
标签: python sql django postgresql