简体   繁体   English

如何在Django或SQL中查询非唯一在一起的值?

[英]How to query Non Unique Together values in Django or SQL?

Let's say I have this model: 假设我有这个模型:

class Contact(BaseModel):
    order = models.ForeignKey(Order, related_name='contacts', blank=True, null=True)
    type = models.CharField(max_length=15, choices=TYPES, blank=True))

I want to find all orders where order and type are not unique together. 我想找到的所有订单,其中ordertype不是唯一的一起。

For example, there is order A and there are related contacts: 例如,有一个order A并且有相关的联系人:

Contact(order=orderA, type='broker')
Contact(order=orderA, type='broker')
Contact(order=orderA, type='delivery')

I want to find this orderA because this order and type='broker' are not unique together in Contact model. 我想找到此orderA因为此订单和type='broker'Contact模型中不是唯一的。

And then there is orderB and these related contacts: 然后是orderB和这些相关的联系人:

Contact(order=orderB, type='broker')
Contact(order=orderB, type='delivery')

I don't want this orderB because it and the field type are unique in Contact model. 我不需要此orderB因为它和字段typeContact模型中是唯一的。

I tried using annonate() of Django but failed to relate these two fields. 我尝试使用Django的annonate() ,但未能关联这两个字段。

Is it possible to do this with Django queries? 是否可以使用Django查询执行此操作?

If not, a slight hint of how I could do it in SQL would be greatly appreciated. 如果没有,我将非常感谢我在SQL中如何做到这一点的一点提示。

Thank you very much. 非常感谢你。

You could use a SQL query like: 您可以使用类似以下的SQL查询:

select distinct order_id
from (
    select order_id, type
    from Contact
    group by order_id, type
    having count(*) > 1);

The "order" column is shown as "order_id" because that's the way Django names columns. “ order”列显示为“ order_id”,因为这是Django命名列的方式。

You could write a couple methods to solve this problem. 您可以编写一些方法来解决此问题。 I might have gone over board writing these methods for you but regardless heres an explaination. 我可能已经为您编写了这些方法,但无论如何都没有解释。 def equal_to takes self and some other contact, returns true if that contact is the same order and type else false. def equal_to接受self和其他联系方式,如果该联系方式顺序相同,则返回true,然后输入else。 def all_not_unique returns a list of all not unique contact objects with no duplicates. def all_not_unique返回所有没有重复的非唯一联系人对象的列表。 And should be called like, not_unique = Contact.all_not_unique() . 应该像not_unique = Contact.all_not_unique()那样调用。

def equal_to(self, other):
    assert(self.id != other.id)
    if self.order.id == other.order.id:
        if self.type == other.type:
            return True
    return false

@classmethod
def all_not_unique(cls):
    query_set = cls.objects.all()
    not_unique_query_set = []
    for contact_one in query_set:
        found = False
        for contact_two in query_set:
            if not found:
                if contact_one.id != contact_two.id:
                    if contact_one.equal_to(contact_two):
                        not_unique_query_set.append(contact_one)
                        found = True

This should do the trick 这应该可以解决问题

qs = (Contact.objects.values('order','type')
         .annotate(cnt=models.Count('pk'))
         .filter(cnt__gt=1))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM