如何使用Oracle CTE进行此类查询?

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

我有一个如下所示的查询:

SELECT m.Name, (m.Value + NVL(a1.Value1, 0) + NVL(a2.Value2,0) + NVL(a3.Value3,0) "Value"
FROM m MainTable
LEFT JOIN Additional1 a1 ON (...)
LEFT JOIN Additional2 a2 ON (...)
LEFT JOIN Additional3 a3 ON (...)
WHERE (conditions on m)
ORDER BY 1;

这些查询为每个Name生成多行。

我需要使用以下逻辑将每个Name限制为一行:包括Value最接近给定Name的平均值的行。

有些东西告诉我,CTE应该允许更紧凑的代码,并希望更有效的实现,所以我不需要多次重复几乎相同的查询。

你能指点我正确的方向吗?

sql oracle11g common-table-expression
1个回答
0
投票

CTE可以提供帮助,但我认为关键是分析功能。首先,您可以使用分析函数计算每个名称的平均值。然后,您可以对差异的绝对值进行排名。

这是CTE的版本:

with t as (
    SELECT m.Name,
           (m.Value + NVL(a1.Value1, 0) + NVL(a2.Value2,0) + NVL(a3.Value3,0) "Value"
    FROM m MainTable
         LEFT JOIN Additional1 a1 ON (...)
         LEFT JOIN Additional2 a2 ON (...)
         LEFT JOIN Additional3 a3 ON (...)
   WHERE (conditions on m)
)
select t.*
from (select t.*,
             row_number() over (partition by name order by avgdiff) as seqnum
      from (select t.*,
                   abs(value - avg(value) over (partition by name)) as AvgDiff
            from t
           ) t
     ) t
where seqnum = 1
© www.soinside.com 2019 - 2024. All rights reserved.