【问题标题】:SQl apply where clause to only one fieldSQL 仅将 where 子句应用于一个字段
【发布时间】:2014-07-15 17:00:26
【问题描述】:

我想将 WHERE 子句应用于我的选择查询的一个字段。互联网告诉我在选择字段的行中使用 CASE WHEN,然后删除 where 子句。但后来有人告诉我,我的“selected non aggregate values must be part of the associated group."

原始查询如下所示:

SELECT 
    CAST(EVENT_TIMESTAMP AS DATE) AS Date1, 
    COUNT(DISTINCT EMAIL) END AS Subs, 
    SUM(DWELL_MINUTES) AS Dwell
FROM VwNIMEventFct
INNER JOIN VwNIMUserDim ON VwNIMUserDim.NIM_USER_ID = VwNIMEventFct.NIM_USER_ID
INNER JOIN TmpNIMSalesForceDB ON VwNIMUserDim.USER_EMAIL_ADDRESS = EMAIL


WHERE Date1 >= '2013-11-01'
// The problem is here, in the AND clause
AND (SUBSCRIPTION_END_DATE > VwNIMEventFct.EVENT_TIMESTAMP OR SUBSCRIPTION_END_DATE 
IS NULL)

GROUP BY Date1
ORDER BY Date1

然后我在做一些搜索后更改了查询:

  SELECT 
    CAST(EVENT_TIMESTAMP AS DATE) AS Date1, 
    CASE WHEN (SUBSCRIPTION_END_DATE > Date1 OR SUBSCRIPTION_END_DATE IS NULL)
        THEN COUNT(DISTINCT TmpNIMSalesForceDB.EMAIL) END AS Subs, 
    SUM(VwNIMEventFct.DWELL_MINUTES) AS Dwell
    FROM RDMAVWSANDBOX.VwNIMEventFct
   INNER JOIN VwNIMUserDim ON VwNIMUserDim.NIM_USER_ID = VwNIMEventFct.NIM_USER_ID
   INNER JOIN TmpNIMSalesForceDB ON VwNIMUserDim.USER_EMAIL_ADDRESS = EMAIL
   WHERE Date1 >= '2013-11-01'
   GROUP BY Date1
   ORDER BY Date1

我想选择: 1)查询中的“Date1”日期,然后, 2) 对于每个日期,SUBSCRIPTION_END_DATE 为 NULL 或将来(大于 Date1)的不同电子邮件地址的计数, 3)一个字段的总和(我这里很好)

第 2 点怎么做?

根据答案编辑: 选择查询的这一部分是否忽略并因此不计算空白记录 SUBSCRIPTION_END_DATE 为空?

SELECT 
    COUNT(DISTINCT CASE  WHEN TmpNIMSalesForceDB.SUBSCRIPTION_END_DATE > Date1 OR TmpNIMSalesForceDB.SUBSCRIPTION_END_DATE IS NULL
             THEN TmpNIMSalesForceDB.EMAIL END) AS Subs, 

我需要计算 SUBSCRIPTION_END_DATE 为空白/null 或这些日期在 Date1 之后的所有记录。

【问题讨论】:

    标签: sql teradata


    【解决方案1】:

    您需要将 CASE 语句放在 COUNT 中,而不是相反,因为它需要针对每一行进行评估(该行应该属于哪种情况),然后在每个组中聚合(该组中有多少行属于非空组)。

     COUNT(DISTINCT CASE WHEN (SUBSCRIPTION_END_DATE > Date1 OR SUBSCRIPTION_END_DATE IS NULL)
        THEN TmpNIMSalesForceDB.EMAIL END) AS Subs
    

    COUNT 将忽略 CASE 语句中缺少 ELSE 子句隐式留下的 NULL,因此只计算满足条件的行中不同的 EMAIL 值。

    【讨论】:

    • “COUNT 将忽略由于 CASE 语句中缺少 ELSE 子句而隐含地留下的 NULL”,这会改变事情。我更改了查询,它运行得很好,但结果不是我期望看到的。我需要在日期为空时包含而不是忽略 - 当 SUBSCRIPTION_END_DATE 为空白时计算电子邮件。
    • 我想你可能误解了。将 CASE 想象成一个函数,它返回一些值以在输出中使用或传递给其他函数;如果该行与指定条件匹配,则 CASE 的结果为指定值;如果不匹配任何条件,则使用 E​​LSE 子句的值;如果没有 ELSE,则结果为 NULL。这与被检查的输入是否包含 NULL 无关。
    • 啊,是的,我误会了。所以条件满足了——做事(计数)。看起来我还有另一个问题,因为数字不是预期的。感谢您在这方面的帮助
    • 查看您的问题,原始查询与 VwNIMEventFct.EVENT_TIMESTAMP 进行了比较,但修改后的查询与 Date1 进行了比较。这能解释你目前的差异吗?
    • Date1 派生自 VwNIMEventFct.EVENT_TIMESTAMP。我原以为可能是这样。仍在调查中
    【解决方案2】:

    case 语句放在count 函数内。

    SELECT 
        CAST(EVENT_TIMESTAMP AS DATE) AS Date1, 
        COUNT(DISTINCT(CASE 
                 WHEN SUBSCRIPTION_END_DATE > Date1 OR SUBSCRIPTION_END_DATE IS NULL
                 THEN TmpNIMSalesForceDB.EMAIL END)) AS Subs, 
        SUM(VwNIMEventFct.DWELL_MINUTES) AS Dwell
    FROM RDMAVWSANDBOX.VwNIMEventFct
        INNER JOIN VwNIMUserDim 
            ON VwNIMUserDim.NIM_USER_ID = VwNIMEventFct.NIM_USER_ID
        INNER JOIN TmpNIMSalesForceDB 
            ON VwNIMUserDim.USER_EMAIL_ADDRESS = EMAIL
    WHERE Date1 >= '2013-11-01'
    GROUP BY Date1
    ORDER BY Date1
    

    【讨论】:

    • 这有点难以判断,因为没有示例数据,但我认为您将不得不将 EMAIL 添加到 Group By 子句而不是使用 DISTINCT。然后你可以有 "sum(case ... 1 else 0 end) as Subs"
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-11
    • 2023-03-24
    • 2021-12-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多