T-Sql聚合查询

时间:2016-04-29 22:15:05

标签: sql-server tsql aggregate-functions

任何人都可以帮我弄清楚我对这个查询做错了什么。我正在尝试从包含电子邮件发送给客户端的电子邮件状态的表中过滤一些记录。我需要删除所有的EmailIds状态为已发送(1)和已退回(0)。除了这两种状态之外的任何东西都被视为已交付(4)。所以输出只包含一个状态为Delivered(4)的EmailId,所有那些没有状态为1和0的EmailId。在下面的例子中,我也应该看到EmailId 4的状态为已交付

这是我的样本设置。非常感谢你们给我提供的任何帮助

create table #status
(
    Id int,
    Name varchar(100)
)

insert into #status (Id, Name)
values (0, 'Bounced'), (1, 'Sent'), (2, 'Clicked'),
       (3, 'Opened'), (4, 'Delivered')

create table #email
(
    EmailId int ,
    Email varchar(100),
    StatusId int 
)

insert into #email (EmailId, email, StatusId)
values (1, 'rjoseph@gmail.com', 1), (1, 'rjoseph@gmail.com', 0),
       (2, 'nathan@comcast.net', 1), (2, 'nathan@comcast.net', 2),
       (2, 'nathan@comcast.net', 3), (3, 'nora@comcast.net', 1),
       (3, 'nora@comcast.net', 2), (3, 'nora@comcast.net', 3),
       (4, 'neha@comcast.net', 1)

select
    e.EmailId
into 
    #temp
from
    #email e
inner join #status st
    on st.Id = e.StatusId
where
    (e.StatusId not in (1,0))
group by
    e.EmailId

drop table #temp
drop table #email
drop table #status

1 个答案:

答案 0 :(得分:2)

这是达到这个目标的一种方式(你可以在没有临时表的情况下做到这一点,但我在这里这样做是为了遵循你自己的语法)。第一个查询获取匹配1 AND 0的行。第二个查询返回第一个查询中不存在的电子邮件ID:

SELECT EmailID
INTO #temp
FROM #email
WHERE StatusID = 0
AND EXISTS (SELECT 1 FROM #email WHERE StatusID = 1)

SELECT DISTINCT e.EmailID
FROM #email AS e LEFT JOIN #temp AS t
ON e.EmailID = t.EmailID
WHERE t.EmailID IS NULL

BTW:SELECT 1 FROM ...与StatusID#1没有任何关系。这可能看起来令人困惑,因为我使用了SELECT 1,但它可能是SELECT 5或SELECT' Z'。它几乎毫无意义。

这里是没有临时表的相同查询:

SELECT DISTINCT e.EmailID
FROM #email AS e 
WHERE e.EmailID NOT IN (
  SELECT EmailID
  FROM #email
  WHERE StatusID = 0
  AND EXISTS (SELECT 1 FROM #email WHERE StatusID = 1)
)