如何比较元组的特定值与 SQL 中两个表的 AVG 值
How to compare specific Values of tuples with an AVG-value in SQL over two tables
我正在搜索一个查询,其中可以 "join" 具有所有元组的特定值的 AVG 值。
所以我有以下数据(主题是关于公司的数据集):
表 1:
ID 姓名国家/地区 Class
表2:
ID 值 1 值 2
我设法获得了特定国家/地区的 Value1/Value2 和一家公司的 Class 的 AVG 值。
现在,我试图显示 Country/Class 的公司数量,这些公司在其 class 的 AVG 值的 5% 值范围内。
我尝试了所有我能想象到的可能性。我正在努力解决的问题是,在嵌套查询中不可能返回多个值。
谁能给我一个解决这个问题的方法?
我认为你需要这样的东西:
with data as (
select cname, country, class, value1/value2 vv
, avg(value1/value2) over (partition by country, class) av
from vals join companies using (id) )
select country, class, count(case when vv/av < 0.2 then 1 end) cnt
from data group by country, class
它是如何工作的?在每个 id 的第一步中,我们收集有关按国家/地区划分的平均值 (value1/value2) 和 class 的信息。
这是子查询data
中的列av
,使用解析函数avg()
进行计算。这个子查询的输出是:
CNAME COUNTRY CLASS VV AV
---------- ---------- ----- ---------- ----------
GHI China A 30 30
ABC Russia A 5 32,5
JKL Russia A 60 32,5
DEF Russia B 3 3
接下来我们只需要按国家/地区和 class 对数据进行分组,并附上符合您条件的公司数量的信息。
所以完整查询的输出是(我使用了 20%,将条件 vv/av < 0.2
更改为您需要的任何内容):
COUNTRY CLASS CNT
---------- ----- ----------
Russia A 1
China A 0
Russia B 0
您可以通过将 AVG()
用作 window(分析)函数来执行此操作:
SELECT id, name, country, class, company_value FROM (
SELECT t1.id, t1.name, t1.country, t1.class, t2.value1/t2.value2 AS company_value
, AVG(t2.value1/t2.value2) OVER ( PARTITION BY t1.country, t1.class ) AS avg_value
FROM table1 t1 INNER JOIN table2 t2
ON t1.id = t2.id
) WHERE company_value BETWEEN avg_value * 0.95 AND avg_value * 1.05;
在上面的查询中,我使用 0.95
和 1.05
分别表示 1 - 0.05
和 1 + 0.05
(在 5% 以内)。要获得计数,只需使用上面的作为子查询(或者 CTE,如果你更习惯的话):
SELECT country, class, COUNT(*) FROM (
SELECT id, name, country, class, company_value FROM (
SELECT t1.id, t1.name, t1.country, t1.class, t2.value1/t2.value2 AS company_value
, AVG(t2.value1/t2.value2) OVER ( PARTITION BY t1.country, t1.class ) AS avg_value
FROM table1 t1 INNER JOIN table2 t2
ON t1.id = t2.id
) WHERE company_value BETWEEN avg_value * 0.95 AND avg_value * 1.05
);
我正在搜索一个查询,其中可以 "join" 具有所有元组的特定值的 AVG 值。
所以我有以下数据(主题是关于公司的数据集):
表 1: ID 姓名国家/地区 Class
表2: ID 值 1 值 2
我设法获得了特定国家/地区的 Value1/Value2 和一家公司的 Class 的 AVG 值。 现在,我试图显示 Country/Class 的公司数量,这些公司在其 class 的 AVG 值的 5% 值范围内。 我尝试了所有我能想象到的可能性。我正在努力解决的问题是,在嵌套查询中不可能返回多个值。
谁能给我一个解决这个问题的方法?
我认为你需要这样的东西:
with data as (
select cname, country, class, value1/value2 vv
, avg(value1/value2) over (partition by country, class) av
from vals join companies using (id) )
select country, class, count(case when vv/av < 0.2 then 1 end) cnt
from data group by country, class
它是如何工作的?在每个 id 的第一步中,我们收集有关按国家/地区划分的平均值 (value1/value2) 和 class 的信息。
这是子查询data
中的列av
,使用解析函数avg()
进行计算。这个子查询的输出是:
CNAME COUNTRY CLASS VV AV
---------- ---------- ----- ---------- ----------
GHI China A 30 30
ABC Russia A 5 32,5
JKL Russia A 60 32,5
DEF Russia B 3 3
接下来我们只需要按国家/地区和 class 对数据进行分组,并附上符合您条件的公司数量的信息。
所以完整查询的输出是(我使用了 20%,将条件 vv/av < 0.2
更改为您需要的任何内容):
COUNTRY CLASS CNT
---------- ----- ----------
Russia A 1
China A 0
Russia B 0
您可以通过将 AVG()
用作 window(分析)函数来执行此操作:
SELECT id, name, country, class, company_value FROM (
SELECT t1.id, t1.name, t1.country, t1.class, t2.value1/t2.value2 AS company_value
, AVG(t2.value1/t2.value2) OVER ( PARTITION BY t1.country, t1.class ) AS avg_value
FROM table1 t1 INNER JOIN table2 t2
ON t1.id = t2.id
) WHERE company_value BETWEEN avg_value * 0.95 AND avg_value * 1.05;
在上面的查询中,我使用 0.95
和 1.05
分别表示 1 - 0.05
和 1 + 0.05
(在 5% 以内)。要获得计数,只需使用上面的作为子查询(或者 CTE,如果你更习惯的话):
SELECT country, class, COUNT(*) FROM (
SELECT id, name, country, class, company_value FROM (
SELECT t1.id, t1.name, t1.country, t1.class, t2.value1/t2.value2 AS company_value
, AVG(t2.value1/t2.value2) OVER ( PARTITION BY t1.country, t1.class ) AS avg_value
FROM table1 t1 INNER JOIN table2 t2
ON t1.id = t2.id
) WHERE company_value BETWEEN avg_value * 0.95 AND avg_value * 1.05
);