如何在 CASE SQL 中将 ANY 运算符添加到 AVG 中

问题描述 投票:0回答:1

我们有一个存储程序,可以对当地报告中的雪况进行平均,然后得出该县的设定百分比。该县被放置在交互式地图上,并应用了颜色深浅。

在只有少数报告的县,即使只有 1 个营业场所,平均值也会设置为 0。这是一个问题,因为颜色表明该县没有开业企业。

我们的解决方案是,如果有一份报告具有“差”、“一般”、“良好”、“优秀”的条件,则将平均值设置为 25;如果有不止一份报告具有这些条件之一,则将平均值设置为 50。

我尝试使用 ANY 运算符实现第一个目标,但我无法实现此目的。我也不知道如何实现第二个目标。

这是当前查询:

ALTER PROCEDURE [dbo].[GetAverageConditionByCounty]
(   
    @SiteId int = 100
)
AS
BEGIN
    SET NOCOUNT ON;

    SELECT cg.Name,
    AVG(ISNULL(CASE sn.Condition 
        WHEN 'Poor' THEN 25 
        WHEN 'Fair' THEN 50 
        WHEN 'Good' THEN 75 
        WHEN 'Excellent' THEN 100
        ELSE 0  END,-1)) as average
    FROM Counties cg    
    INNER JOIN BaseReports br ON br.CountyId = cg.Id AND br.IsActive = 1
    INNER JOIN SnowReport sn ON sn.BaseReportId = br.Id 
    WHERE br.SiteId = @SiteId
    GROUP BY cg.Id, cg.Name
    ORDER BY cg.Name
END

以下是原始查询的示例结果:

姓名 平均
A县 100
B县 75
C县 0
D县 0
E县 25

为了使用 ANY() 运算符实现第一个目标,这就是我尝试做的:

ALTER PROCEDURE [dbo].[GetAverageConditionByCounty]
(   
    @SiteId int = 100
)
AS
BEGIN
    SET NOCOUNT ON;

    SELECT cg.Name,
    AVG(ISNULL(CASE sn.Condition 
        WHEN 'Past Peak' THEN 101
        WHEN 'Poor' THEN 25 
        WHEN 'Fair' THEN 50 
        WHEN 'Good' THEN 75 
        WHEN 'Excellent' THEN 100
        WHEN sn.Condition = ANY ('Poor', 'Fair', 'Good', 'Excellent' ) THEN 25
        ELSE 0  END,-1)) as average
    FROM Counties cg    
    INNER JOIN BaseReports br ON br.CountyId = cg.Id AND br.IsActive = 1
    INNER JOIN SnowReport sn ON sn.BaseReportId = br.Id 
    WHERE br.SiteId = @SiteId
    GROUP BY cg.Id, cg.Name
    ORDER BY cg.Name
END

尝试 ANY() 时出错:

  • “=”附近的语法不正确。
  • “Poor”附近的语法不正确。需要“(”或“SELECT”。
  • “THEN”附近的语法不正确。

这是我使用 IN() 运算符的尝试:

ALTER PROCEDURE [dbo].[GetAverageConditionByCounty]
(   
    @SiteId int = 100
)
AS
BEGIN
    SET NOCOUNT ON;

    SELECT cg.Name,
    AVG(ISNULL(CASE sn.Condition 
        WHEN 'Past Peak' THEN 101
        WHEN 'Poor' THEN 25 
        WHEN 'Fair' THEN 50 
        WHEN 'Good' THEN 75 
        WHEN 'Excellent' THEN 100
        WHEN sn.Condition IN ('Poor', 'Fair', 'Good', 'Excellent' ) THEN 25
        ELSE 0  END,-1)) as average
    FROM Counties cg    
    INNER JOIN BaseReports br ON br.CountyId = cg.Id AND br.IsActive = 1
    INNER JOIN SnowReport sn ON sn.BaseReportId = br.Id 
    WHERE br.SiteId = @SiteId
    GROUP BY cg.Id, cg.Name
    ORDER BY cg.Name
END

以下是尝试 IN() 时的错误:

  • “IN”附近的语法不正确。
  • “THEN”附近的语法不正确。需要“,”、“AND”或“Or”。
sql sql-server case average any
1个回答
0
投票

你似乎想要更多这样的东西:

case count(case when sn.Condition in ('Poor', 'Fair', 'Good', 'Excellent') then 1 end)
    -- if those are all the possibilities then just use count(*) instead
    when 1 then 25
    when 2 then 50
    else avg(case sn.Condition 
                 when 'Poor' then 25 
                 when 'Fair' then 50 
                 when 'Good' then 75 
                 when 'Excellent' then 100
                 else 0 end)
end as "average"

它还让您体验两种类型的

case
表达方式。

您还可以利用总是被忽略的空值来保证计算结果不会低于 25。由于对计算的贡献最低的是 25,因此不可能低于该平均值,尽管在没有输入的情况下仍可能计算为 null。 (

else null
也是未明确指定时的默认行为):

coalesce(avg(case sn.Condition 
            when 'Poor' then 25 
            when 'Fair' then 50 
            when 'Good' then 75 
            when 'Excellent' then 100
            else null end), 0) as "average"
© www.soinside.com 2019 - 2024. All rights reserved.