SQL 值与列平均值之间的差异计算不正确

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

因此,我编写了一个查询来查找 2022 年国家 GDP 的列表,其中每个国家的 GDP 与平均 GDP 存在差异。但当我检查计算时,差异值是错误的,所以我添加了(gdp_value - 0)计算列,它显示用于(gdp_value - 平均值)计算的GDP与实际GDP值不同。有人可以解释一下为什么 SQL 使用不同的值进行计算吗?

这是 SQL 代码:

select
    rank() over(order by gdp_value desc) as 'rank',
    country_name,
    gdp_value,
    (gdp_value - 0) as gdp_test,
    average,
    (gdp_value - average) as difference
from gdp, (select avg(gdp_value) as average
            from gdp
            where country_code in
                (select code
                from world.country
                where continent = 'Africa')
                    and year = '2022') subq
where country_code in
    (select code
    from world.country
    where continent = 'Africa')
        and year = '2022'
group by country_name, gdp_value, average
order by gdp_value desc;

这是我得到的结果:

排名 国家/地区名称 gdp_值 gdp_测试 平均 差异
1 尼日利亚 477000000000 477000007680 56499913809.23077 420500093870.7692
1 埃及 阿拉伯共和国 477000000000 477000007680 56499913809.23077
3 南非 406000000000 406000009216 56499913809.23077 349500095406.7692
4 阿尔及利亚 192000000000 192000000000 56499913809.23077 135500086190.76923
5 摩洛哥 134000000000 134000001024 56499913809.23077 77500087214.76923

(抱歉,可视化效果不好,我不知道还能怎么做)

(我尝试了这里的一个问题中建议的

cast(gdp_value as decimal(15,2))
,但它只是使“gdp_value”与“gdp_test”相同,但我仍然不明白如何计算与实际gdp_value的差异)

sql average calculation
1个回答
0
投票

您的

cast(gdp_value as decimal(15,2))
有效,这意味着这就是答案。这意味着您必须在每个使用 gpd_value 的地方使用它,这当然可能很痛苦。

例如:

avg(gdp_value)
变成
avg(cast(gdp_value as decimal(15,2)))

如果您的 SQL 引擎支持通用表表达式 (CTE) - 这是编写 SQL 的另一种风格,我认为这将使您受益。首先,更容易调试和阅读。其次,你可以在自己的基础上进行构建,这样当你遇到类似的事情时,你只需要修复 gdp_value 一次,然后其余的就可以在此基础上构建。

例如,也许是这样的:

WITH gdp_fixed AS (
    SELECT code, country_name, cast(gdp_value as decimal(15,2)) AS gdp_value
    FROM gpd
),
countries AS (
    SELECT distinct code
    FROM world.country
    WHERE continent = 'Africa'
    AND year='2022'
),
-- instead of an IN() I am just joining, but you can do either
gpd_filtered AS (
    SELECT *
    FROM gdp_fixed A
    INNER JOIN countries B
    ON A.country_code = B.code
),
averages AS (
    SELECT avg(gpd_value) AS average
    FROM gpd_filtered
),
merged AS (
    SELECT *
    FROM gdp_filtered, averages
)
SELECT rank() over(order by gdp_value desc) as 'rank',
    country_name,
    gdp_value,
    (gdp_value - 0) as gdp_test,
    average,
    (gdp_value - average) as difference
from merged
group by country_name, gdp_value, average
order by gdp_value desc;

即使您不完全喜欢这个查询,您也可以尝试类似的方法,使用子查询来修复

gdp_value
一次。

© www.soinside.com 2019 - 2024. All rights reserved.