SQL 子查询计算

SQL subqueries calculations

我有这个 table:

╔═════╤═══════╤═══════╗
║ ID  │ Group │ Value ║
╠═════╪═══════╪═══════╣
║ ID1 │ 1     │ 10    ║
╟─────┼───────┼───────╢
║ ID2 │ 1     │ 5     ║
╟─────┼───────┼───────╢
║ ID2 │ 1     │ 4     ║
╟─────┼───────┼───────╢
║ ID2 │ 1     │ 6     ║
╟─────┼───────┼───────╢
║ ID1 │ 2     │ 1     ║
╟─────┼───────┼───────╢
║ ID2 │ 2     │ 7     ║
╟─────┼───────┼───────╢
║ ID2 │ 2     │ 8     ║
╟─────┼───────┼───────╢
║ ID2 │ 2     │ 3     ║
╟─────┼───────┼───────╢
║ ID3 │ 3     │ 6     ║
╟─────┼───────┼───────╢
║ ID2 │ 3     │ 4     ║
╟─────┼───────┼───────╢
║ ID2 │ 3     │ 1     ║
╟─────┼───────┼───────╢
║ ID2 │ 3     │ 9     ║
╚═════╧═══════╧═══════╝

我想执行以下操作:

  1. 查找 ID = ID1 的所有组
  2. 提取与ID = ID1属于同一组的ID2的平均值

ID1只存在于Group1和Group2中。因此 ID2 的平均值 第 1 组 = (5+4+6)/3 = 5

和第 2 组 = (7+8+3)/3 = 6

  1. 计算每组 ID1 值相对于 ID2 平均值的百分比。

第 1 组 = (10*100%)/5 = 200%

第 2 组 = (1*100%)/6 = 16%

我知道如何分别执行这些步骤,但我不知道如何在第二个查询中使用第一个查询(组)的列表。

Search_Item = 'ID1'

Select Group FROM MyTable WHERE ID = 'ID1'

-> Return 1 和 2

Select AVG(Value) FROM MyTable WHERE ID = 'ID2' AND Group = '1' 
Select AVG(Value) FROM MyTable WHERE ID = 'ID2' AND Group = '2'

如有任何帮助,我们将不胜感激。

你可以这样做:

SELECT t.group,NVL(avg(s.value),0),(MAX(t.value)*100/NVL(avg(s.value),1)) as Perc
FROM(
    SELECT group,max(value) as value FROM MyTable WHERE ID = 'ID1' group by group) t
LEFT OUTER JOIN Mytable s
 ON(t.group = s.group and s.ID = 'ID2')
GROUP BY t.group

您可以像这样使用单个 table 扫描来完成此操作:

SELECT   "GROUP",
         100 * SUM( CASE id WHEN 'ID1' THEN value END )
             / AVG( CASE id WHEN 'ID2' THEN value END )
           AS Percentage
FROM     MyTable
GROUP BY "GROUP"
HAVING   COUNT( CASE id WHEN 'ID1' THEN 1 END ) > 0;

输出

GROUP PERCENTAGE
----- ----------
    1        200
    2 16.6666667

如果您只想要只有一行 IDID1 的组,则将最后一行更改为:

HAVING   COUNT( CASE id WHEN 'ID1' THEN 1 END ) = 1;

您可能有一个包含 ID1 行的组,并且 ID2 行的总和为零(如果您允许零值或负值)——查询将抛出ORA-01476: divisor is equal to zero 异常。如果你想防止这种情况发生,那么你可以使用:

SELECT   "GROUP",
         100 * SUM( CASE id WHEN 'ID1' THEN value END )
             / CASE AVG( CASE id WHEN 'ID2' THEN value END )
                    WHEN 0 THEN NULL
                    ELSE AVG( CASE id WHEN 'ID2' THEN value END )
                    END
           AS Percentage
...