从排除域列表中排除电子邮件地址
Exclude email address from a list of excluded domains
我有一个电子邮件客户端,可以像您在 gmail 收件箱中看到的那样列出电子邮件。
所有电子邮件都存储在 Postgres 9.3.5 数据库中。
我想要实现的部分功能是允许用户阻止来自域列表的传入电子邮件,例如@spam.com,
我有 this sqlfiddle,它包含模式的缩减版本,我有一个 emails
table 和一个 email_participants
table。用户可以选择 select 他们想要排除的域,例如他们可以选择排除来自 yahoo.com、hotmail.com 等的电子邮件。
目前查询基本是这样的:
SELECT subject, ep.email_id, kind, ep.user_id, ep.contact_id
FROM emails e
INNER JOIN
email_participants ep
ON ep.email_id = e.id
-- and ep.address domain doees not include *.yahoo.com, *.hotmail.com or whatever
WHERE kind = 'sent'
ORDER BY sent_at DESC;
我想将排除的域存储在 table 中,但我不知道如何使用类似查询从一组数据中排除。
这可能不完全正确,但足以让你到达那里......尝试:
and substring(ea.address from '@.*') not in ('@yahoo.com', '@hotmail.com')
在上下文中:
SELECT subject, ep.email_id, kind, ep.user_id, ep.contact_id, ea.address
FROM emails e
INNER JOIN
email_participants ep
ON ep.email_id = e.id
JOIN email_addresses ea
ON ep.contact_id = ea.contact_id
and substring(ea.address from '@.*') not in ('@yahoo.com', '@hotmail.com')
WHERE kind = 'sent'
ORDER BY sent_at DESC;
The user can choose to select as many domains they want to exclude
这表明在后端您需要一个 table,其中包含 user_id 和 exclude_domain 作为列:
CREATE TABLE user_excludedomain (
user_id INTEGER NOT NULL,
domain VARCHAR(255) NOT NULL,
CONSTRAINT user_excludedomain_pkey PRIMARY KEY (user_id, domain),
CONSTRAINT user_id_fkey FOREIGN KEY (user_id)
REFERENCES users (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE CASCADE);
然后在您的 select 查询中,向此 table 添加一个 left join
并构造 where clause
以删除连接从该 [= 中产生一行的行22=]。
即
SELECT
e.subject,
ep.email_id,
e.kind,
ep.user_id,
ep.contact_id
FROM emails e
INNER JOIN email_participants ep
ON ep.email_id = e.id
-- left join all domains to be excluded
LEFT JOIN user_excludedomain uex
ON uex.user_id = ep.user_id
AND uex.domain = SUBSTRING(ea.address from '@.*')
WHERE kind = 'sent'
AND uex.user_id IS NULL -- pick only rows where the left join returns null (i.e. the excluded domain is not joined)
ORDER BY sent_at DESC;
我有一个电子邮件客户端,可以像您在 gmail 收件箱中看到的那样列出电子邮件。
所有电子邮件都存储在 Postgres 9.3.5 数据库中。
我想要实现的部分功能是允许用户阻止来自域列表的传入电子邮件,例如@spam.com,
我有 this sqlfiddle,它包含模式的缩减版本,我有一个 emails
table 和一个 email_participants
table。用户可以选择 select 他们想要排除的域,例如他们可以选择排除来自 yahoo.com、hotmail.com 等的电子邮件。
目前查询基本是这样的:
SELECT subject, ep.email_id, kind, ep.user_id, ep.contact_id
FROM emails e
INNER JOIN
email_participants ep
ON ep.email_id = e.id
-- and ep.address domain doees not include *.yahoo.com, *.hotmail.com or whatever
WHERE kind = 'sent'
ORDER BY sent_at DESC;
我想将排除的域存储在 table 中,但我不知道如何使用类似查询从一组数据中排除。
这可能不完全正确,但足以让你到达那里......尝试:
and substring(ea.address from '@.*') not in ('@yahoo.com', '@hotmail.com')
在上下文中:
SELECT subject, ep.email_id, kind, ep.user_id, ep.contact_id, ea.address
FROM emails e
INNER JOIN
email_participants ep
ON ep.email_id = e.id
JOIN email_addresses ea
ON ep.contact_id = ea.contact_id
and substring(ea.address from '@.*') not in ('@yahoo.com', '@hotmail.com')
WHERE kind = 'sent'
ORDER BY sent_at DESC;
The user can choose to select as many domains they want to exclude
这表明在后端您需要一个 table,其中包含 user_id 和 exclude_domain 作为列:
CREATE TABLE user_excludedomain (
user_id INTEGER NOT NULL,
domain VARCHAR(255) NOT NULL,
CONSTRAINT user_excludedomain_pkey PRIMARY KEY (user_id, domain),
CONSTRAINT user_id_fkey FOREIGN KEY (user_id)
REFERENCES users (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE CASCADE);
然后在您的 select 查询中,向此 table 添加一个 left join
并构造 where clause
以删除连接从该 [= 中产生一行的行22=]。
即
SELECT
e.subject,
ep.email_id,
e.kind,
ep.user_id,
ep.contact_id
FROM emails e
INNER JOIN email_participants ep
ON ep.email_id = e.id
-- left join all domains to be excluded
LEFT JOIN user_excludedomain uex
ON uex.user_id = ep.user_id
AND uex.domain = SUBSTRING(ea.address from '@.*')
WHERE kind = 'sent'
AND uex.user_id IS NULL -- pick only rows where the left join returns null (i.e. the excluded domain is not joined)
ORDER BY sent_at DESC;