【问题标题】:T- Sql aggregate queryT-Sql 聚合查询
【发布时间】:2016-04-29 22:15:04
【问题描述】:

谁能帮我弄清楚我在这个查询中做错了什么。我正在尝试从包含发送给客户的电子邮件的表中过滤一些记录以及电子邮件的状态。我需要消除所有具有Sent(1) 和 Bounced(0) 的状态。除了这两种状态之外的任何状态都被视为已交付 (4)。因此,对于所有那些没有状态 1 和 0 的 EmailId,输出仅包含状态为 Delivered(4) 的 EmailId。在下面的示例中,我应该也看到状态为 Delivered 的 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

【问题讨论】:

  • 我对你试图完成的事情感到困惑。这似乎是一个非常简单的请求,但有一个不必要的复杂解决方案。您有多个 SELECT 语句返回三个单独的结果集。如果您只是想过滤掉 0 和 1 状态,那么您已经在第一个 SELECT 查询中这样做了(除非您将这些行插入到临时表中,因此您永远看不到它们)。
  • @Boyd,我刚刚摆脱了我拥有的额外选择语句。我正在尝试消除任何同时具有 0 和 1 statusIds 的 EmaiId。除此之外的任何东西都应该与 EmailId 合二为一下一列的列和已交付状态(4)(没有重复的 EmailId)。我的聚合查询中没有看到 EmailId 4
  • 啊,我明白了。您看不到 EmailID 4 的原因是您使用 WHERE e.StatusId NOT IN(1,0) 将其过滤掉。这是一个 OR 语句,本质上是说“statusID 不是 1 OR 0”。我会发布一个答案。
  • 非常感谢@Boyd

标签: sql-server tsql aggregate-functions


【解决方案1】:

这是一种笨拙的方法(您可以在没有临时表的情况下执行此操作,但我这样做是为了遵循您自己的语法)。第一个查询获取匹配 1 和 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

顺便说一句: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)
)

【讨论】:

  • ,非常感谢。我有这个查询的起点来解决我的更大问题。非常感谢您帮助我
猜你喜欢
  • 2018-08-06
  • 1970-01-01
  • 1970-01-01
  • 2019-06-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-30
  • 1970-01-01
相关资源
最近更新 更多