试图按语句理解分区

时间:2014-05-16 15:26:23

标签: sql teradata window-functions

我已经看过其他关于让人们围绕分区和排序的帖子。有点得到它但仍然有点困惑。

以下是我的同事提供的查询:

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

1 个答案:

答案 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

(或任何具体条件)。

如果您需要有关电子邮件或联接的更多信息,请加入原始表格。

当您对此过程感到满意时,您可以考虑使用窗口/分析函数来执行相同的操作。我担心的是,您真正想要的条件可能会变得更加复杂,并且分两步执行逻辑(获取电子邮件,获取其他信息)将帮助您完善它。