AVG 函数在 sql 中给出了错误的值

AVG function is giving wrong values in sql

我有 3 个 tables 地区、国家、供应商。我的供应商 table 中共有 3000 条记录。我想找到特定国家的平均账户余额。我尝试了 s_acctbal 的 AVG(计数)值,但它给了我 3000 作为 AVG 值,无论我如何更改为其他国家而不是中国。 我发现了类似的问题,但这些方法并没有解决我的问题。我怎样才能得到特定国家的平均账户余额?

CREATE TABLE REGION(

R_REGIONKEY NUMBER(12)  NOT NULL,
R_NAME      CHAR(25)    NOT NULL,
R_COMMENT   VARCHAR(152)    NOT NULL,
CONSTRAINT REGION_PKEY PRIMARY KEY(R_REGIONKEY),
CONSTRAINT REGION_CHECK1 CHECK(R_REGIONKEY >= 0) );

CREATE TABLE NATION(
N_NATIONKEY NUMBER(12)  NOT NULL,
N_NAME      CHAR(25)    NOT NULL,
N_REGIONKEY NUMBER(12)  NOT NULL,
N_COMMENT   VARCHAR(152)    NOT NULL,
CONSTRAINT NATION_PKEY PRIMARY KEY (N_NATIONKEY),
CONSTRAINT NATION_FKEY1 FOREIGN KEY (N_REGIONKEY)
REFERENCES REGION(R_REGIONKEY),
CONSTRAINT NATION_CHECK1 CHECK(N_NATIONKEY >= 0) );

CREATE TABLE PART(
P_PARTKEY   NUMBER(12)  NOT NULL,
P_NAME      VARCHAR(55) NOT NULL,
P_MFGR      VARCHAR(25) NOT NULL,
P_BRAND     CHAR(10)    NOT NULL,
P_TYPE      VARCHAR(25) NOT NULL,
P_SIZE      NUMBER(12)  NOT NULL,
P_CONTAINER     CHAR(10)    NOT NULL,
P_RETAILPRICE   NUMBER(12,2)    NOT NULL,
P_COMMENT   VARCHAR(23) NOT NULL,
CONSTRAINT PART_PEKEY PRIMARY KEY (P_PARTKEY),
CONSTRAINT PART_CHECK1 CHECK(P_PARTKEY >= 0),
CONSTRAINT PART_CHECK2 CHECK(P_SIZE >= 0),
CONSTRAINT PART_CHECK3 CHECK(P_RETAILPRICE >= 0) );

CREATE TABLE SUPPLIER(
S_SUPPKEY   NUMBER(12)  NOT NULL, 
S_NAME      CHAR(25)    NOT NULL,
S_ADDRESS   VARCHAR(40) NOT NULL,
S_NATIONKEY NUMBER(12)  NOT NULL,
S_PHONE     CHAR(15)    NOT NULL,
S_ACCTBAL   NUMBER(12,2)    NOT NULL,
S_COMMENT   VARCHAR(101)    NOT NULL,
CONSTRAINT SUPPLIER_PKEY PRIMARY KEY (S_SUPPKEY),
CONSTRAINT SUPPLIER_FKEY1 FOREIGN kEY (S_NATIONKEY)
REFERENCES NATION(N_NATIONKEY),
CONSTRAINT SUPPLIER_CHECK1 CHECK(S_SUPPKEY >= 0) );

这是总记录;

 SQL> select count(*) from supplier;
    
      COUNT(*)
    ----------
          3000

这是我的 sql 代码;

select n_name, s_name, s_acctbal, AVG(counted)
from (select Count(s_acctbal) AS counted from supplier), supplier, nation, region
where s_nationkey = n_nationkey
and r_regionkey = n_regionkey
and n_name = 'CHINA'
group by n_name, s_name, s_acctbal;

我得到的一些输出(我没有全部粘贴,因为有 145 行);

N_NAME            S_NAME             S_ACCTBAL AVG(COUNTED)
------------------------- ------------------------- ---------- ------------
CHINA             Supplier#000001610           3120.6          3000
CHINA             Supplier#000001674            340.14         3000
CHINA             Supplier#000001876           9804.43         3000
CHINA             Supplier#000001145           8752.68         3000
CHINA             Supplier#000001168           1154.17         3000
CHINA             Supplier#000001249            999.08         3000
CHINA             Supplier#000000793           7044.94         3000
CHINA             Supplier#000001106           3079.79         3000
CHINA             Supplier#000001117           3620.41         3000
CHINA             Supplier#000000027           1887.62         3000
CHINA             Supplier#000000041           6942.67         3000

N_NAME            S_NAME             S_ACCTBAL AVG(COUNTED)
------------------------- ------------------------- ---------- ------------
CHINA             Supplier#000000082           -724.31         3000
CHINA             Supplier#000000395            688.37         3000
CHINA             Supplier#000000499           2518.34         3000
CHINA             Supplier#000002290           8573.93         3000
CHINA             Supplier#000002484           8797.54         3000
CHINA             Supplier#000002664           1095.86         3000
CHINA             Supplier#000002761           3448.45         3000
CHINA             Supplier#000002171           8624.28         3000
CHINA             Supplier#000002231           5973.38         3000
CHINA             Supplier#000001378           7119.9          3000
CHINA             Supplier#000001557           9059.38         3000

N_NAME            S_NAME             S_ACCTBAL AVG(COUNTED)
------------------------- ------------------------- ---------- ------------
CHINA             Supplier#000001843           8670.08         3000
CHINA             Supplier#000002861           6821.08         3000

145 rows selected.

代码显示的问题是: 您想要计数的平均值,AVG 函数需要一组值来计算它们的平均值,但您只发送一个值,即计数的计数。

试试这个代码:

select n_name, s_name, s_acctbal, 
AVG(counted) from (select s_acctbal AS counted from supplier), 
supplier, nation, region 
where s_nationkey = n_nationkey and r_regionkey = n_regionkey and n_name = 'CHINA' 
group by n_name, s_name, s_acctbal;

AVG 函数现在将接收 s_acctbal 列的所有值并计算它们的平均值。

不知道还有没有错误

首先你不需要 REGION table 除非你的问题有什么遗漏。

其次,您需要了解 AVGSUMCOUNT 等聚合函数如何需要 GROUP BY 子句。

第三,您的查询尝试表明您没有完全理解 table 联接。花时间学习它们,因为如果您不知道联接,您就不知道 SQL,句号。练习它们直到它们成为第二天性。

对于您的查询,您只需要这些 tables:

  • NATION,获取中国的国家密钥
  • SUPPLIER,获取供应商名称及其账户余额

按照您的查询尝试的一般方法,查询将如下所示:

select n_name, s_name, AVG(s_acctbal)
from nation, supplier
where n_nationkey = s_nationkey
  and n_name = 'CHINA'
group by n_name, s_name

聚合:注意group by n_name, s_name。作为一般规则,当您的 SELECT 具有类似于 AVG(something) 的聚合函数时,您需要按 select 列表中不是聚合函数的每个值进行分组。您的 select 列表有这个:

  • n_name - 不是聚合函数
  • s_name - 不是聚合函数
  • AVG(s_acctbal) - 是聚合函数

因此,按 n_name, s_name.

分组

加入: 稍微说一下,因为你需要更深入的研究。我的答案中的查询通过使用这部分语法加入:

from nation, supplier
where n_nationkey = s_nationkey

它来自 nationsupplier table。但是,您如何定义哪些 nationsupplier 记录在一起?使用连接,在这种情况下,它是在 WHERE 子句中定义的(您也可以使用 JOIN 子句,但在您准备好时开始使用):where n_nationkey = s_nationkey.