【问题标题】:django distinct queryset from queryset-valuesdjango 从查询集值中区分查询集
【发布时间】:2019-07-01 20:42:59
【问题描述】:

我有一个User,它可以有多个Accounts。每个Account 上可以有多个Units。 我建立一个过滤字典并获取相关单位:

units = Unit.objects.filter(**unit_filter)

但是,我也想获得不同的用户。我可以很容易地得到他们的 id:

user_dicts = units.values('account__user').distinct()

或者更准确地说:

user_ids = [rec.get('account__user') for rec in 
            units.values('account__user').distinct()]

然后我可以使用User.objects.filter(id__in=user_ids) 过滤用户。 (我也可以使用生成器表达式代替列表推导,但这不是重点。)

我不确定,但评估 id in 在我看来效率不高。有没有更好的方法从过滤单元中获取唯一用户?


编辑:

我添加了 SQL 查询(没有测试它们,可能是错误的)以明确我在 Django ORM 中尝试做的事情。实际上我正在尝试使用JOIN 而不是WHERE 子句。

我希望这样:

WITH selected_units AS
  (SELECT id, account_id FROM units)
SELECT DISTINCT u.id FROM user u 
  JOIN account a on a.user_id=u.id
  JOIN unit ut ON ut.account=a.id 
  JOIN selected_units s ON s.id=ut.id;

但是id_in 我明白了:

WITH selected_units AS
  (SELECT id, account_id FROM units)
SELECT DISTINCT u.id FROM user u 
  JOIN account a on a.user_id=u.id 
  JOIN unit ut ON ut.account_id=a.id 
WHERE ut.id IN (SELECT id FROM selected_units);

【问题讨论】:

    标签: python django django-queryset distinct


    【解决方案1】:

    我认为您可以使用子查询来做到这一点,如下所示:

    User.objects.filter(account__unit__in=units)
    

    或者不那么漂亮:

    User.objects.filter(id__in=units.values_list('account__user__id', flat=True))
    

    【讨论】:

    • 您好,感谢您的回复。我过去使用values_list(),但没有意识到我可以使用flat=True,然后使用distinct()。但是,总是有这个id in 测试,虽然它看起来更整洁一些。我在问题中添加了 sql 查询,以使我想要做的事情更加明显。
    猜你喜欢
    • 2021-12-10
    • 1970-01-01
    • 2021-05-02
    • 2020-10-26
    • 2017-01-12
    • 2012-04-26
    • 2013-04-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多