简体   繁体   English

分组其他字段时,SQL CASE和CAST一起导致聚合错误

[英]SQL CASE and CAST together causes aggregation error when grouping other fields

I have a query that has to convert values into decimals and divide them. 我有一个查询,必须将值转换为小数并除以它们。 I need to only divide when a value is greater than 0, otherwise it throws an error. 我只需要在值大于0时进行除法,否则会引发错误。 My query is below. 我的查询如下。 For some reason adding the CASE statement causes an aggregation error. 由于某种原因,添加CASE语句会导致聚合错误。 I've seen examples that say to wrap in a SUM, but that won't work for my case. 我已经看到了一些示例,这些示例说要包含在SUM中,但不适用于我的情况。 Any suggestions? 有什么建议么?

SELECT
    EmailName,
    SUM(Sent) as Sent,
    SUM(Delivered) as Delivered,
    SUM(UniqueOpens) as UniqueOpens,
    SUM(TotalOpens) as TotalOpens,
    SUM(UniqueClicks) as UniqueClicks,
    SUM(TotalClicks) as TotalClicks,
    SUM(Unsubscribes) as Unsubscribes,
    CAST(SUM(UniqueOpens) AS FLOAT)/CAST(SUM(Delivered) AS FLOAT) as OpenRate
FROM 
    [Non Triggered Sends Last Month]
GROUP BY 
    EmailName

This works if UniqueOpens is greater than 0, but fails otherwise 如果UniqueOpens大于0,则此方法有效,否则,则失败

This throws an aggregation warning 这引发了聚合警告

SELECT
    EmailName,
    SUM(Sent) as Sent,
    SUM(Delivered) as Delivered,
    SUM(UniqueOpens) as UniqueOpens,
    SUM(TotalOpens) as TotalOpens,
    SUM(UniqueClicks) as UniqueClicks,
    SUM(TotalClicks) as TotalClicks,
    SUM(Unsubscribes) as Unsubscribes,
    CASE WHEN UniqueOpens > 0 THEN CAST(SUM(UniqueOpens) AS FLOAT)/CAST(SUM(Delivered) AS FLOAT) ELSE CAST(SUM(UniqueOpens) AS FLOAT) END as OpenRate
FROM 
    [Non Triggered Sends Last Month]
GROUP BY 
    EmailName

An error occurred while checking the query syntax. 检查查询语法时发生错误。 Errors: Column 'C7211451.Non Triggered Sends Last Month.UniqueOpens' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause. 错误:选择列表中的列'C7211451.Non Triggered Sends Last Month.UniqueOpens'在选择列表中无效,因为它既不在聚合函数中也不在GROUP BY子句中。

I think you just need to SUM(UniqueOpens) 我想你只需要求和SUM(UniqueOpens)

SELECT
EmailName,
SUM(Sent) as Sent,
SUM(Delivered) as Delivered,
SUM(UniqueOpens) as UniqueOpens,
SUM(TotalOpens) as TotalOpens,
SUM(UniqueClicks) as UniqueClicks,
SUM(TotalClicks) as TotalClicks,
SUM(Unsubscribes) as Unsubscribes,
CASE WHEN SUM(UniqueOpens) > 0 THEN CAST(SUM(UniqueOpens) AS FLOAT)/CAST(SUM(Delivered) AS FLOAT) ELSE CAST(SUM(UniqueOpens) AS FLOAT) END as OpenRate
FROM [Non Triggered Sends Last Month]
GROUP BY EmailName

Your case statement needs to have a SUM in it too. 您的案例陈述也需要包含SUM。

CASE WHEN UniqueOpens > 0

needs to be 需要是

CASE WHEN SUM(UniqueOpens) > 0

Why do you want a value when the unique delivered is non-positive? 当交付的唯一性为非正数时,为什么要一个值? I would just go for NULL : 我只想去NULL

 SUM(UniqueOpens) * 1.0 / NULLIF(SUM(Delivered), 0) as OpenRate

However, if you want to prevent division by zero, I would suggest comparing the denominator , not the numerator: 但是,如果要防止被零除,我建议比较分母而不是分子:

 (CASE WHEN SUM(Delivered) > 0
       THEN SUM(UniqueOpens) * 1.0 / SUM(Delivered)
       ELSE 0  -- I'm assuming these SUM(Delivered) is a non-negative integer
  END) as OpenRate

I usually use the shorthand of * 1.0 to prevent integer division. 我通常使用* 1.0的缩写来防止整数除法。 Conversion to float is equally good. 转换为浮点数同样好。

Use sum Aggregation on Case statement 在案例陈述中使用总和聚合

SELECT
EmailName,
SUM(Sent) as Sent,
SUM(Delivered) as Delivered,
SUM(UniqueOpens) as UniqueOpens,
SUM(TotalOpens) as TotalOpens,
SUM(UniqueClicks) as UniqueClicks,
SUM(TotalClicks) as TotalClicks,
SUM(Unsubscribes) as Unsubscribes,
SUM(CASE WHEN UniqueOpens > 0 THEN 
CAST(UniqueOpens AS FLOAT)/CAST(Delivered AS FLOAT)
 ELSE CAST(UniqueOpens AS FLOAT) )END as OpenRate
FROM [Non Triggered Sends Last Month]
GROUP BY EmailName

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM