我有以下型号:
class Message(Model):
url = URLField("URL")
email = EmailField("E-Mail")
contacted = BooleanField("Contacted", default=False)
使用示例数据:
| url | email | contacted |
+-----+-----------------+-----------+
| foo | foo@example.com | N |
| bar | bar@example.com | N |
| baz | foo@example.com | Y |
我想选择从未联系过电子邮件地址的所有不同行(通过电子邮件地址)。使用此示例数据,bar@example.com
行将是唯一返回的行。
答案 0 :(得分:2)
这将返回您想要的记录:
not_contacted = Message.objects.exclude(
email__in=Message.objects.filter(contacted=True).values('email')
)
这样做的好处是只运行一个查询。您的查询将如下所示:
SELECT
messages_message.id, messages_message.url, messages_message.email, messages_message.contacted
FROM
Messages
WHERE NOT
(messages_message.email IN
( SELECT U0.email from messages_message U0 WHERE U0.contacted = True )
)
请注意,对于许多记录而言,此查询可能不是最佳记录,但它可能适用于大多数用途。
答案 1 :(得分:1)
DROP SCHEMA tmp CASCADE;
CREATE SCHEMA tmp ;
SET search_path=tmp;
CREATE TABLE massage
( zurl varchar NOT NULL
, zemail varchar NOT NULL
, contacted boolean
);
INSERT into massage(zurl, zemail, contacted) VALUES
( 'foo', 'foo@example.com', False)
,( 'bar', 'bar@example.com', False)
,( 'baz', 'foo@example.com', True)
;
SELECT
DISTINCT zemail AS zemail
, MIN(zurl) AS zurl
FROM massage m
WHERE NOT EXISTS (
SELECT *
FROM massage nx
WHERE nx.zemail = m.zemail
AND nx.contacted = True
)
GROUP BY zemail;
如果给定电子邮件地址有多个记录,则上述记录会选择具有“最低”URL的记录。如果你想要它们,查询会更简单:
SELECT m.zurl, m.zemail
FROM massage m
WHERE NOT EXISTS (
SELECT *
FROM massage nx
WHERE nx.zemail = m.zemail
AND nx.contacted = True
) ;