0

次のようなクエリがあります。

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

次のロジックを使用して、各行を1行に制限する必要がありNameます。特定の名前の平均値に最も近い値の行を含めます。

CTEはよりコンパクトなコードを可能にし、できればより効果的な実装を可能にする必要があるので、実質的に同じクエリを何度も繰り返す必要はありません。

私を正しい方向に向けてもらえますか?

4

1 に答える 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
于 2013-03-06T01:58:48.740 に答える