SQL加入电子邮件,域和限制

时间:2018-01-06 00:25:02

标签: sql oracle

我需要返回电子邮件别名域数量和限制信息。我在搞清楚SQL语句时遇到了麻烦。

我有四张桌子:

CREATE TABLE person 
  ( 
     person_id   VARCHAR2(9 byte) NOT NULL ENABLE, 
     internal_id VARCHAR2(9 byte) NOT NULL ENABLE 
  )

INSERT INTO person 
VALUES      ('012345678', 
             '987654321')

INSERT INTO person 
VALUES      ('24680123', 
             '32108642')

CREATE TABLE group 
  ( 
     internal_id VARCHAR2(9 byte) NOT NULL ENABLE, 
     group_id    VARCHAR2(30 byte) NOT NULL ENABLE 
  )

INSERT INTO group 
VALUES      ('987654321', 
             'alumni')

INSERT INTO group 
VALUES      ('987654321', 
             'retiree')

INSERT INTO group 
VALUES      ('32108642', 
             'random')

INSERT INTO group 
VALUES      ('987654321', 
             'other')

CREATE TABLE email_alias 
  ( 
     person_id   VARCHAR2(9 byte) NOT NULL ENABLE, 
     email_alias VARCHAR2(70 byte) NOT NULL ENABLE 
  )

INSERT INTO email_alias 
VALUES      ('012345678', 
             'person@school.edu')

INSERT INTO email_alias 
VALUES      ('012345678', 
             'per_son@school.edu')

INSERT INTO email_alias 
VALUES      ('012345678', 
             'person@random.com')

INSERT INTO email_alias 
VALUES      ('012345678', 
             'random@random.com')

CREATE TABLE domain_limit 
  ( 
     group_id     VARCHAR2(30 byte) NOT NULL ENABLE, 
     alias_domain VARCHAR2(30 byte) NOT NULL ENABLE,
     limit        NUMBER NOT NULL ENABLE
  )

INSERT INTO domain_limit 
VALUES      ('retiree', 
             '@school.edu',
             5)

INSERT INTO domain_limit 
VALUES      ('retiree', 
             '@school.net',
             2)

INSERT INTO domain_limit 
VALUES      ('employee', 
             '@school.edu',
             25)

INSERT INTO domain_limit 
VALUES      ('employee', 
             '@school.net',
             2)

INSERT INTO domain_limit 
VALUES      ('alumni', 
             '@school.net',
             2)

INSERT INTO domain_limit 
VALUES      ('student', 
             '@school.edu',
             1)

INSERT INTO domain_limit 
VALUES      ('student', 
             '@school.net',
             2)

我希望显示以下内容:

quantity | alias_domain  | limit 
--------------------------------
2        | @random.com   | 0
0        | @school.net   | 25
0        | @school.edu   | 2

部分问题是有人可能输入的email_alias与表格中的某个域不匹配,因为某一点上没有正则表达式。我们使用一个人所属的组来确定他们可能拥有的最大别名数。它们可能属于多个组,允许它们访问同一域的别名。我们不会将它们添加到一起,而是选择给定域的最大限制。

我可以让它显示

quantity | alias_domain  | limit 
--------------------------------
2        | @random.com   | 0

quantity | alias_domain  | limit 
--------------------------------
0        | @school.net   | 25
0        | @school.edu   | 2

但我尝试的其他事情最终结束

quantity | alias_domain  | limit 
--------------------------------
2        | @school.net   | 25
2        | @school.edu   | 2

以下是我尝试过的一些示例:

select count(regexp_substr(lower(d.email_alias), c.alias_domain)) as "quantity", 
         c.alias_domain  as "alias_domain", 
         nvl(max(c.limit), 0)  as "limit" 
  from   iam.person a 
         left join groups b 
                on a.internal_id = b.internal_id 
         join domain_limit c 
           on b.group_id = c.group_id 
         left join iam.email_alias d 
                on a.person_id = d.person_id 
  where  a.person_id = :PERSON_ID 
  group  by c.alias_domain

我也尝试了类似的事情:

select count(regexp_substr(lower(d.email_alias), c.alias_domain)) as "quantity", 
             nvl(c.alias_domain, regexp_substr(d.email_alias, '@.+')) as "alias_domain", 
             nvl(max(c.limit), 0) as "limit"     
from   iam.person a 
       left join groups b 
            on a.internal_id = b.internal_id 
       join domain_limit c 
            on b.group_id = c.group_id 
       left join iam.email_alias d 
            on a.person_id = d.person_id 
where  a.person_id = :PERSON_ID 
group  by nvl(c.alias_domain, regexp_substr(d.email_alias, '@.+'))

当我使用以下代码时

select distinct 
count(nvl(c.alias_domain, regexp_substr(d.email_alias, '@.+'))) as quantity,
nvl(c.alias_domain, regexp_substr(d.email_alias, '@.+')) as alias_domain,
nvl(max(c.limit),0) as limit
from person a
join group b
on a.internal_id = b.internal_id
left join domain_limit c
on b.group_id = c.group_id
left join email_alias d
on a.person_id = d.person_id
where a.person_id = :PERSON_ID
group by nvl(c.alias_domain, regexp_substr(d.email_alias, '@.+'));

我得到了

quantity | domain | limit
--------------------------
2   | @school.edu   | 25
6   | @school.net   | 2
96  | @random.com   | 0

在我的套装中,我有2封random.com电子邮件。和48组。 1组给了我25个school.edu的限制,3个组给了我2个school.net别名的限制。

我用这个

解决了问题
select max(quantity) as quantity,
alias_domain, max(limit)
from (select count(email_alias) as quantity,
regexp_substr(email_alias, '@.+') as alias_domain,
0 as limit
from email_alias
where person_id = :PERSON_ID
group by regexp_substr(email_alias, '@.+'), 0
union
select 0 as quantity,
alias_domain,
max(limit)
from iam.person a
join gro.person_group b
on a.person_id = b.person_id
join domain_limit c
on b.group_id = c.group_id
where a.person_id = :PERSON_ID
group by alias_domain, 0)
group by alias_domain;

如果你看到一种更清洁的方式,请告诉我。

1 个答案:

答案 0 :(得分:0)

select max(quantity) as quantity,
alias_domain, max(limit)
from (select count(email_alias) as quantity,
regexp_substr(email_alias, '@.+') as alias_domain,
0 as limit
from email_alias
where person_id = :PERSON_ID
group by regexp_substr(email_alias, '@.+'), 0
union
select 0 as quantity,
alias_domain,
max(limit)
from iam.person a
join gro.person_group b
on a.person_id = b.person_id
join domain_limit c
on b.group_id = c.group_id
where a.person_id = :PERSON_ID
group by alias_domain, 0)
group by alias_domain;
相关问题