我已经看过其他关于让人们围绕分区和排序的帖子。有点得到它但仍然有点困惑。
以下是我的同事提供的查询:
SELECT EMAIL, SUBSCRIPTION_NAME, SOURCE, BILLING_SYSTEM,
RATE_PLAN, NEXT_CHARGE_DATE, SERVICE_ACTIVATION_DATE, CONTRACT_EFFECTIVE_DATE,
SUBSCRIPTION_END_DATE, STATUS, LAST_MODIFIED_DATE, PRODUCT_NAME,
RATE_PLAN_NAME, LOAD_DATE
FROM theDB
QUALIFY COUNT(*) OVER (PARTITION BY EMAIL,CONTRACT_EFFECTIVE_DATE ) > 1
此查询是否以简单的英语说明只返回选定的字段,其中CONTRACT_EFFECTIVE_DATE的记录数对于每个EMAIL多次出现?
另一种方式是这样做,它不运行(我正在使用Teradata并收到错误消息“聚合函数使用不当” - 当我看到该消息时,我应该认为“使用QUALIFY和PARTITION BY?”) :
SELECT EMAIL, SUBSCRIPTION_NAME, SOURCE, BILLING_SYSTEM,
RATE_PLAN, NEXT_CHARGE_DATE, SERVICE_ACTIVATION_DATE, CONTRACT_EFFECTIVE_DATE,
SUBSCRIPTION_END_DATE, STATUS, LAST_MODIFIED_DATE, PRODUCT_NAME,
RATE_PLAN_NAME, LOAD_DATE
FROM RDMATBLSANDBOX.TmpNIMSalesForceDB
WHERE COUNT(CONTRACT_EFFECTIVE_DATE) >1
GROUP BY EMAIL
答案 0 :(得分:2)
不完全。您的查询(如果运行)将为每封电子邮件返回一行(至少在MySQL解释此非标准语法时)。原始版本将为每封电子邮件返回多行。
等效查询基本上是:
select q.*
from (<your query here>
) q join
(select EMAIL, CONTRACT_EFFECTIVE_DATE
from theDB
group by EMAIL, CONTRACT_EFFECTIVE_DATE
having count(*) > 1
) filter
on q.email = filter.email and q.CONTRACT_EFFECTIVE_DATE = e.CONTRACT_EFFECTIVE_DATE;
存在微妙的差异,这通常是无关紧要的。您的版本将识别其中一个或两个字段中的NULL
值。即使存在重复,此版本也会对其进行过滤。
编辑:
如果您只想要电子邮件列表,请使用group by
:
select email
from theDB t
where CONTRACT_EFFECTIVE_DATE between @start and @end
group by email
having count(*) = 5
(或任何具体条件)。
如果您需要有关电子邮件或联接的更多信息,请加入原始表格。
当您对此过程感到满意时,您可以考虑使用窗口/分析函数来执行相同的操作。我担心的是,您真正想要的条件可能会变得更加复杂,并且分两步执行逻辑(获取电子邮件,获取其他信息)将帮助您完善它。