如何在两个表中将元组的特定值与SQL中的AVERAGE值进行比较

时间:2015-03-23 09:57:35

标签: sql oracle join average

我正在搜索一个查询,在这里可以使用所有元组的特定值“加入”AVG值。

所以我有以下数据(主题是关于公司的数据集):

表1: ID名称国家/地区类别

表2: ID Value1 Value2

我设法获得了公司特定国家/地区的Value1 / Value2的AVG值。 现在我试图显示一个国家/班级的公司数量,它们属于同类AVG值的5%值范围。 我尝试了所有可能的想象力。我正在努力解决的问题是,在嵌套查询中不可能返回多个值。

有人能给我一个解决这个问题的方法吗?

2 个答案:

答案 0 :(得分:0)

我认为你需要这样的东西:

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

SQLFiddle

它是如何工作的?在每个id的第一步中,我们收集有关按国家和类别划分的平均值(value1 / value2)的信息。 这是子查询av中的列data,分析函数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

接下来,我们只需按国家/地区和班级对数据进行分组,并附上有关符合条件的公司数量的信息。 因此,完整查询的输出是(我使用20%,将条件vv/av < 0.2更改为您需要的任何内容):

COUNTRY    CLASS        CNT
---------- ----- ----------
Russia     A              1
China      A              0
Russia     B              0

答案 1 :(得分:0)

您可以使用AVG()作为窗口(分析)函数来执行此操作:

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.951.05使用了1 - 0.051 + 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
);